@solana/connector 0.1.3 → 0.1.4

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.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +460 -1082
  3. package/dist/{chunk-TIW3EQPC.js → chunk-CLXM6UEE.js} +120 -103
  4. package/dist/chunk-CLXM6UEE.js.map +1 -0
  5. package/dist/{chunk-7CKCRY25.js → chunk-D6PZY5G6.js} +69 -77
  6. package/dist/chunk-D6PZY5G6.js.map +1 -0
  7. package/dist/chunk-LUZWUZ5N.js +2012 -0
  8. package/dist/chunk-LUZWUZ5N.js.map +1 -0
  9. package/dist/{chunk-HPENTIPE.mjs → chunk-N3Q2J2FG.mjs} +51 -55
  10. package/dist/chunk-N3Q2J2FG.mjs.map +1 -0
  11. package/dist/chunk-P5MWBDFG.mjs +298 -0
  12. package/dist/chunk-P5MWBDFG.mjs.map +1 -0
  13. package/dist/chunk-RIQH5W7D.js +311 -0
  14. package/dist/chunk-RIQH5W7D.js.map +1 -0
  15. package/dist/chunk-U64YZRJL.mjs +1984 -0
  16. package/dist/chunk-U64YZRJL.mjs.map +1 -0
  17. package/dist/{chunk-TKJSKXSA.mjs → chunk-YTCSTE3Q.mjs} +35 -19
  18. package/dist/chunk-YTCSTE3Q.mjs.map +1 -0
  19. package/dist/compat.d.mts +4 -2
  20. package/dist/compat.d.ts +4 -2
  21. package/dist/compat.js +3 -3
  22. package/dist/compat.mjs +1 -1
  23. package/dist/headless.d.mts +146 -18
  24. package/dist/headless.d.ts +146 -18
  25. package/dist/headless.js +144 -111
  26. package/dist/headless.mjs +3 -2
  27. package/dist/index.d.mts +6 -5
  28. package/dist/index.d.ts +6 -5
  29. package/dist/index.js +207 -126
  30. package/dist/index.mjs +4 -3
  31. package/dist/react.d.mts +707 -67
  32. package/dist/react.d.ts +707 -67
  33. package/dist/react.js +64 -16
  34. package/dist/react.mjs +2 -2
  35. package/dist/{transaction-signer-D3csM_Mf.d.mts → transaction-signer-D9d8nxwb.d.mts} +3 -1
  36. package/dist/{transaction-signer-D3csM_Mf.d.ts → transaction-signer-D9d8nxwb.d.ts} +3 -1
  37. package/dist/{wallet-standard-shim-C1tisl9S.d.ts → wallet-standard-shim-Cp4vF4oo.d.mts} +133 -6
  38. package/dist/{wallet-standard-shim-Cg0GVGwu.d.mts → wallet-standard-shim-DC_Z7DS-.d.ts} +133 -6
  39. package/package.json +16 -12
  40. package/dist/chunk-5ZUVZZWU.mjs +0 -180
  41. package/dist/chunk-5ZUVZZWU.mjs.map +0 -1
  42. package/dist/chunk-7CKCRY25.js.map +0 -1
  43. package/dist/chunk-FTD7F7CS.js +0 -314
  44. package/dist/chunk-FTD7F7CS.js.map +0 -1
  45. package/dist/chunk-HPENTIPE.mjs.map +0 -1
  46. package/dist/chunk-MPZFJEJK.mjs +0 -298
  47. package/dist/chunk-MPZFJEJK.mjs.map +0 -1
  48. package/dist/chunk-SMUUAKC3.js +0 -186
  49. package/dist/chunk-SMUUAKC3.js.map +0 -1
  50. package/dist/chunk-TIW3EQPC.js.map +0 -1
  51. package/dist/chunk-TKJSKXSA.mjs.map +0 -1
package/README.md CHANGED
@@ -3,255 +3,139 @@ title: @solana/connector
3
3
  description: Production-ready wallet connector for Solana applications
4
4
  ---
5
5
 
6
- **ConnectorKit is your Solana wallet infrastructure.** A headless, framework-agnostic wallet connector built on Wallet Standard with powerful transaction signing, event system, and performance optimizations that just work.
6
+ **ConnectorKit is your Solana wallet infrastructure.** A headless, framework-agnostic wallet connector built on Wallet Standard that just work.
7
7
 
8
8
  ![npm](https://img.shields.io/npm/v/@solana/connector)
9
- ![Bundle Size](https://img.shields.io/bundlephobia/minzip/@solana/connector)
9
+ ![Bundle Size](https://img.shields.io/badge/bundle-~45KB-gzip-green)
10
10
  ![TypeScript](https://img.shields.io/badge/TypeScript-100%25-blue)
11
- ![Test Coverage](https://img.shields.io/badge/coverage-80%25+-green)
12
11
 
13
12
  ### Why ConnectorKit?
14
13
 
15
- - **Clean Transaction API**: Unified interface for signing and sending—no more wallet-specific logic
16
- - **Production Ready**: Event system, health checks, error boundaries, and monitoring built-in
17
- - **Better Performance**: 40-60% fewer re-renders via optimized state management
18
- - **Universal Compatibility**: Drop-in replacement for @solana/wallet-adapter
19
- - **Framework Agnostic**: React, Vue, Svelte, or vanilla JavaScript
20
-
21
- ### Architecture
22
-
23
- - **Language**: TypeScript with full type safety
24
- - **Standard**: Built on Wallet Standard protocol
25
- - **Frameworks**: React hooks + headless core for any framework
26
- - **Mobile**: Solana Mobile Wallet Adapter integration
27
- - **Storage**: Enhanced persistence with SSR support
28
-
29
- ### Features
30
-
31
- - Wallet Standard compliance with multi-wallet support
32
- - Clean transaction signer abstraction
33
- - Comprehensive event system for analytics
34
- - Connection pooling for better performance
35
- - Health checks and diagnostics
36
- - Auto-connect and account management
37
- - Network switching (mainnet, devnet, testnet, custom)
38
- - Browser polyfills for universal compatibility
39
- - Debug panel for development
40
- - Wallet Adapter compatibility bridge
41
- - 80%+ test coverage
14
+ - **Wallet Standard First**: Built on the official Wallet Standard protocol for universal wallet compatibility
15
+ - **Modern & Legacy Support**: Works with both `@solana/kit` (web3.js 2.0) and `@solana/web3.js` (legacy)
16
+ - **Framework Agnostic**: React hooks + headless core for Vue, Svelte, or vanilla JavaScript
17
+ - **Production Ready**: Event system for analytics, health checks for diagnostics, error boundaries for React apps
18
+ - **Enhanced Storage**: Automatic validation, SSR fallback, and error handling out of the box
19
+ - **Mobile Support**: Built-in Solana Mobile Wallet Adapter integration
42
20
 
43
21
  ---
44
22
 
45
23
  ## Quick Start
46
24
 
47
- Install ConnectorKit:
25
+ ### 1. Install
48
26
 
49
27
  ```bash
50
- pnpm add @solana/connector
51
- # or
52
28
  npm install @solana/connector
53
29
  # or
30
+ pnpm add @solana/connector
31
+ # or
54
32
  yarn add @solana/connector
55
- ```
56
-
57
- Basic usage:
58
-
59
- ```typescript
60
- import {
61
- ConnectorProvider,
62
- getDefaultConfig,
63
- useConnector,
64
- useAccount,
65
- useTransactionSigner
66
- } from '@solana/connector';
67
-
68
- // 1. Wrap your app
69
- function App() {
70
- return (
71
- <ConnectorProvider config={getDefaultConfig({ appName: "My App" })}>
72
- <WalletButton />
73
- </ConnectorProvider>
74
- );
75
- }
76
-
77
- // 2. Connect wallet
78
- function WalletButton() {
79
- const { wallets, select, connected, disconnect } = useConnector();
80
- const { address, formatted } = useAccount();
81
-
82
- if (!connected) {
83
- return wallets.map(w => (
84
- <button key={w.name} onClick={() => select(w.name)}>
85
- Connect {w.name}
86
- </button>
87
- ));
88
- }
89
-
90
- return (
91
- <>
92
- <span>{formatted}</span>
93
- <button onClick={disconnect}>Disconnect</button>
94
- </>
95
- );
96
- }
97
-
98
- // 3. Sign transactions
99
- function SendTransaction() {
100
- const { signer, ready } = useTransactionSigner();
101
-
102
- const handleSend = async () => {
103
- const signature = await signer.signAndSendTransaction(transaction);
104
- };
33
+ # or
34
+ bun add @solana/connector
35
+ ```
36
+
37
+ ### 2. Setup Provider (once in your app root)
38
+
39
+ ```typescript
40
+ 'use client';
41
+
42
+ import { useMemo } from 'react';
43
+ import { AppProvider } from '@solana/connector/react';
44
+ import { getDefaultConfig, getDefaultMobileConfig } from '@solana/connector/headless';
45
+
46
+ export function Providers({ children }: { children: React.ReactNode }) {
47
+ const connectorConfig = useMemo(() => {
48
+ // Optional: Get custom RPC URL from environment variable
49
+ const customRpcUrl = process.env.SOLANA_RPC_URL;
50
+
51
+ // Optional: Create custom cluster configuration
52
+ const clusters = customRpcUrl
53
+ ? [
54
+ {
55
+ id: 'solana:mainnet' as const,
56
+ label: 'Mainnet (Custom RPC)',
57
+ name: 'mainnet-beta' as const,
58
+ url: customRpcUrl,
59
+ },
60
+ {
61
+ id: 'solana:devnet' as const,
62
+ label: 'Devnet',
63
+ name: 'devnet' as const,
64
+ url: 'https://api.devnet.solana.com',
65
+ },
66
+ ]
67
+ : undefined;
68
+
69
+ return getDefaultConfig({
70
+ appName: 'My App',
71
+ appUrl: 'https://myapp.com',
72
+ autoConnect: true,
73
+ enableMobile: true,
74
+ clusters,
75
+ });
76
+ }, []);
105
77
 
106
- return <button onClick={handleSend} disabled={!ready}>Send</button>;
78
+ const mobile = useMemo(
79
+ () =>
80
+ getDefaultMobileConfig({
81
+ appName: 'My App',
82
+ appUrl: 'https://myapp.com',
83
+ }),
84
+ [],
85
+ );
86
+
87
+ return (
88
+ <AppProvider connectorConfig={connectorConfig} mobile={mobile}>
89
+ {children}
90
+ </AppProvider>
91
+ );
107
92
  }
108
93
  ```
109
94
 
110
- **[→ Getting Started](#core-hooks)** - Learn the core hooks
111
-
112
- **[→ Transaction Signer](#transaction-signer)** - Sign and send transactions
113
-
114
- **[→ Event System](#event-system)** - Track wallet events for analytics
115
-
116
- **[→ Framework Guides](#headless-client-vue-svelte-vanilla-js)** - Use with Vue, Svelte, or vanilla JS
117
-
118
- ---
119
-
120
- ## Documentation
121
-
122
- ### Getting Started
123
-
124
- - [Installation](#quick-start)
125
- - [Quick Start Guide](#quick-start)
126
- - [TypeScript SDK](#typescript-sdk)
127
- - [Core Hooks](#core-hooks)
128
- - [Local Development](#local-development)
129
-
130
- ### Production Features
131
-
132
- - [Transaction Signer](#transaction-signer) - Clean signing API
133
- - [Event System](#event-system) - Analytics and monitoring
134
- - [Debug Panel](#debug-panel) - Development tools
135
- - [Connection Pooling](#connection-pooling) - Performance optimization
136
- - [Health Checks](#health-checks) - Diagnostics
137
- - [Wallet Adapter Compatibility](#wallet-adapter-compatibility) - Drop-in replacement
138
-
139
- ### Configuration & Usage
140
-
141
- - [Configuration](#configuration) - Setup options
142
- - [Network Selection](#network-selection) - Cluster management
143
- - [Custom Storage](#custom-storage) - Persistence options
144
- - [Mobile Wallet Adapter](#mobile-wallet-adapter) - Mobile support
145
- - [Advanced Usage](#advanced-usage) - Framework-specific guides
146
-
147
- ### Reference
148
-
149
- - [Complete API Reference](#complete-api-reference)
150
- - [Configuration Functions](#configuration-functions)
151
- - [Transaction Signing API](#transaction-signing-api-new)
152
- - [Event System API](#event-system-api-new)
153
- - [Health Check API](#health-check-api-new)
154
- - [Connection Pool API](#connection-pool-api-new)
155
- - [Utility Functions](#utility-functions)
156
- - [TypeScript Types](#types)
157
-
158
- ### Testing & Performance
159
-
160
- - [Testing](#testing) - Test suite and utilities
161
- - [Performance](#performance) - Bundle size and optimization
162
- - [Browser Compatibility](#browser-compatibility)
163
-
164
- ### Migration & Examples
165
-
166
- - [Migration from wallet-adapter](#migration-from-solanawallet-adapter)
167
- - [Examples](#examples)
168
- - [Supported Wallets](#supported-wallets)
169
-
170
- ---
171
-
172
- ## TypeScript SDK
173
-
174
- ConnectorKit provides React hooks and a headless core for any framework:
95
+ ### 3. Use Hooks (in any component)
175
96
 
176
97
  ```typescript
177
- // React
178
- import { useConnector, useTransactionSigner, useAccount } from '@solana/connector';
179
-
180
- // Headless (Vue, Svelte, vanilla JS)
181
- import { ConnectorClient, getDefaultConfig } from '@solana/connector/headless';
182
-
183
- const client = new ConnectorClient(getDefaultConfig({ appName: 'My App' }));
184
- await client.select('Phantom');
185
- ```
186
-
187
- **[→ API Reference](#complete-api-reference)** - Full TypeScript API documentation
188
-
189
- **[→ Core Hooks](#core-hooks)** - React hooks reference
190
-
191
- **[→ Headless Guide](#headless-client-vue-svelte-vanilla-js)** - Use without React
98
+ 'use client';
192
99
 
193
- ---
194
-
195
- ## Local Development
196
-
197
- ### Prerequisites
198
-
199
- - Node.js 20+ (or 18+)
200
- - pnpm, npm, or yarn
201
- - TypeScript 5.0+
202
-
203
- ### Installation
204
-
205
- ```bash
206
- git clone https://github.com/your-org/connectorkit.git
207
- cd connectorkit
208
- pnpm install
209
- ```
210
-
211
- ### Build
212
-
213
- ```bash
214
- pnpm build
215
- ```
216
-
217
- ### Running Examples
218
-
219
- ```bash
220
- cd examples/react
221
- pnpm dev
222
- ```
223
-
224
- Or run the Vite example:
225
-
226
- ```bash
227
- cd examples/vite
228
- pnpm dev
229
- ```
230
-
231
- ### Local Testing
100
+ import { useConnector, useAccount } from '@solana/connector';
232
101
 
233
- Run all tests:
102
+ export function ConnectButton() {
103
+ const { wallets, select, disconnect, connected, connecting, selectedWallet, selectedAccount } = useConnector();
104
+ const { address, formatted, copy } = useAccount();
234
105
 
235
- ```bash
236
- pnpm test
237
- ```
106
+ if (connecting) {
107
+ return <button disabled>Connecting...</button>;
108
+ }
238
109
 
239
- Run tests in watch mode:
110
+ if (!connected) {
111
+ return (
112
+ <div>
113
+ {wallets.map(w => (
114
+ <button key={w.wallet.name} onClick={() => select(w.wallet.name)}>
115
+ Connect {w.wallet.name}
116
+ </button>
117
+ ))}
118
+ </div>
119
+ );
120
+ }
240
121
 
241
- ```bash
242
- pnpm test:watch
122
+ return (
123
+ <div>
124
+ <button onClick={copy}>{formatted}</button>
125
+ <button onClick={disconnect}>Disconnect</button>
126
+ </div>
127
+ );
128
+ }
243
129
  ```
244
130
 
245
- Generate coverage report:
246
-
247
- ```bash
248
- pnpm test:coverage
249
- ```
131
+ **That's it!** You're ready to go. Everything else below is optional.
250
132
 
251
133
  ---
252
134
 
253
135
  ## Core Hooks
254
136
 
137
+ These are the main hooks you'll use in your components.
138
+
255
139
  ### `useConnector()`
256
140
 
257
141
  Main hook for wallet connection and state.
@@ -264,6 +148,7 @@ function Component() {
264
148
  // State
265
149
  wallets, // WalletInfo[] - All available wallets
266
150
  selectedWallet, // Wallet | null - Currently connected wallet
151
+ selectedAccount, // string | null - Currently selected account address
267
152
  accounts, // AccountInfo[] - Connected accounts
268
153
  connected, // boolean - Connection status
269
154
  connecting, // boolean - Connecting in progress
@@ -275,6 +160,41 @@ function Component() {
275
160
  }
276
161
  ```
277
162
 
163
+ **Real Example** - Connect Button with wallet selection:
164
+
165
+ ```typescript
166
+ 'use client';
167
+
168
+ import { useConnector } from '@solana/connector';
169
+ import { useState } from 'react';
170
+
171
+ export function ConnectButton() {
172
+ const [isModalOpen, setIsModalOpen] = useState(false);
173
+ const { connected, connecting, selectedWallet, selectedAccount, wallets, select } = useConnector();
174
+
175
+ if (connecting) {
176
+ return <button disabled>Connecting...</button>;
177
+ }
178
+
179
+ if (connected && selectedAccount && selectedWallet) {
180
+ const shortAddress = `${selectedAccount.slice(0, 4)}...${selectedAccount.slice(-4)}`;
181
+ return (
182
+ <div>
183
+ <span>{shortAddress}</span>
184
+ <button onClick={() => select(selectedWallet.name)}>Switch Wallet</button>
185
+ </div>
186
+ );
187
+ }
188
+
189
+ return (
190
+ <>
191
+ <button onClick={() => setIsModalOpen(true)}>Connect Wallet</button>
192
+ {/* Wallet selection modal */}
193
+ </>
194
+ );
195
+ }
196
+ ```
197
+
278
198
  ### `useAccount()`
279
199
 
280
200
  Hook for working with the connected account.
@@ -295,6 +215,35 @@ function Component() {
295
215
  }
296
216
  ```
297
217
 
218
+ **Real Example** - Account Switcher for multi-account wallets:
219
+
220
+ ```typescript
221
+ 'use client';
222
+
223
+ import { useAccount } from '@solana/connector';
224
+
225
+ export function AccountSwitcher() {
226
+ const { accounts, address, selectAccount, connected } = useAccount();
227
+
228
+ if (!connected || accounts.length <= 1) {
229
+ return null;
230
+ }
231
+
232
+ return (
233
+ <select
234
+ value={address || ''}
235
+ onChange={e => selectAccount(e.target.value)}
236
+ >
237
+ {accounts.map(account => (
238
+ <option key={account.address} value={account.address}>
239
+ {account.address.slice(0, 6)}...{account.address.slice(-6)}
240
+ </option>
241
+ ))}
242
+ </select>
243
+ );
244
+ }
245
+ ```
246
+
298
247
  ### `useCluster()`
299
248
 
300
249
  Hook for managing Solana network/cluster.
@@ -315,291 +264,280 @@ function Component() {
315
264
  }
316
265
  ```
317
266
 
318
- ---
319
-
320
- ## Production Features
321
-
322
- ### Transaction Signer
323
-
324
- Clean, unified interface for transaction signing operations.
267
+ **Real Example** - Network Selector:
325
268
 
326
269
  ```typescript
327
- import { useTransactionSigner } from '@solana/connector';
328
-
329
- function SendTx() {
330
- const { signer, ready, capabilities } = useTransactionSigner();
331
-
332
- // Check capabilities
333
- console.log('Can sign:', capabilities.canSign);
334
- console.log('Can send:', capabilities.canSend);
335
- console.log('Can sign messages:', capabilities.canSignMessage);
336
- console.log('Batch support:', capabilities.supportsBatchSigning);
337
-
338
- const handleSend = async () => {
339
- if (!signer) return;
340
-
341
- try {
342
- // Sign and send a transaction
343
- const signature = await signer.signAndSendTransaction(transaction);
344
- console.log('Success:', signature);
345
-
346
- // Or just sign without sending
347
- const signed = await signer.signTransaction(transaction);
348
-
349
- // Or sign multiple transactions
350
- const signedBatch = await signer.signAllTransactions([tx1, tx2, tx3]);
351
-
352
- // Or sign and send multiple
353
- const signatures = await signer.signAndSendTransactions([tx1, tx2]);
270
+ 'use client';
354
271
 
355
- } catch (error) {
356
- if (error instanceof TransactionSignerError) {
357
- console.error('Signing error:', error.code, error.message);
358
- }
359
- }
360
- };
272
+ import { useCluster } from '@solana/connector';
361
273
 
362
- return (
363
- <button onClick={handleSend} disabled={!ready}>
364
- Send Transaction
365
- </button>
366
- );
274
+ export function ClusterSelector() {
275
+ const { cluster, clusters, setCluster } = useCluster();
276
+
277
+ return (
278
+ <select
279
+ value={cluster?.id || ''}
280
+ onChange={e => setCluster(e.target.value as SolanaClusterId)}
281
+ >
282
+ {clusters.map(c => (
283
+ <option key={c.id} value={c.id}>
284
+ {c.label}
285
+ </option>
286
+ ))}
287
+ </select>
288
+ );
367
289
  }
368
290
  ```
369
291
 
370
- **Error Handling**:
292
+ ### `useWalletInfo()`
371
293
 
372
- ```typescript
373
- import { isTransactionSignerError, TransactionSignerError } from '@solana/connector';
374
-
375
- try {
376
- await signer.signAndSendTransaction(tx);
377
- } catch (error) {
378
- if (isTransactionSignerError(error)) {
379
- switch (error.code) {
380
- case 'WALLET_NOT_CONNECTED':
381
- // Show connect prompt
382
- break;
383
- case 'FEATURE_NOT_SUPPORTED':
384
- // Show unsupported feature message
385
- break;
386
- case 'SIGNING_FAILED':
387
- // User rejected or signing failed
388
- break;
389
- case 'SEND_FAILED':
390
- // Transaction broadcast failed
391
- break;
392
- }
393
- }
394
- }
395
- ```
396
-
397
- ### Event System
398
-
399
- Track all connector lifecycle events for analytics and monitoring.
294
+ Hook for accessing current wallet metadata.
400
295
 
401
296
  ```typescript
402
- import { useConnectorClient } from '@solana/connector';
403
-
404
- function AnalyticsTracker() {
405
- const client = useConnectorClient();
406
-
407
- useEffect(() => {
408
- if (!client) return;
409
-
410
- // Subscribe to events
411
- const unsubscribe = client.on(event => {
412
- switch (event.type) {
413
- case 'wallet:connected':
414
- analytics.track('Wallet Connected', {
415
- wallet: event.wallet,
416
- account: event.account,
417
- timestamp: event.timestamp,
418
- });
419
- break;
420
-
421
- case 'wallet:disconnected':
422
- analytics.track('Wallet Disconnected');
423
- break;
424
-
425
- case 'cluster:changed':
426
- analytics.track('Network Changed', {
427
- from: event.previousCluster,
428
- to: event.cluster,
429
- });
430
- break;
431
-
432
- case 'error':
433
- errorTracker.captureException(event.error, {
434
- context: event.context,
435
- });
436
- break;
437
- }
438
- });
297
+ import { useWalletInfo } from '@solana/connector';
439
298
 
440
- return unsubscribe;
441
- }, [client]);
442
-
443
- return null;
299
+ function Component() {
300
+ const {
301
+ name, // string | null - Wallet name
302
+ icon, // string | undefined - Wallet icon URL
303
+ wallet, // WalletInfo | null - Full wallet info
304
+ connecting, // boolean - Connection in progress
305
+ } = useWalletInfo();
444
306
  }
445
307
  ```
446
308
 
447
- **Available Events**:
309
+ ---
310
+
311
+ ## Transaction Signing
448
312
 
449
- - `wallet:connected` - Wallet successfully connected
450
- - `wallet:disconnected` - Wallet disconnected
451
- - `wallet:changed` - Selected wallet changed
452
- - `account:changed` - Selected account changed
453
- - `cluster:changed` - Network/cluster changed
454
- - `wallets:detected` - New wallets detected
455
- - `connecting` - Connection attempt started
456
- - `connection:failed` - Connection attempt failed
457
- - `error` - Error occurred
313
+ ConnectorKit provides powerful transaction signing capabilities with support for both legacy `@solana/web3.js` and modern `@solana/kit` APIs.
458
314
 
459
- ### Debug Panel
315
+ ### Modern API (`@solana/kit`)
460
316
 
461
- Floating development panel for instant state visibility.
317
+ Use `useKitTransactionSigner()` for modern, type-safe transaction building:
462
318
 
463
319
  ```typescript
464
- import { ConnectorDebugPanel } from '@solana/connector';
465
-
466
- function App() {
467
- return (
468
- <ConnectorProvider config={config}>
469
- {/* Only visible in development mode */}
470
- {process.env.NODE_ENV === 'development' && <ConnectorDebugPanel />}
471
- <YourApp />
472
- </ConnectorProvider>
473
- );
474
- }
475
- ```
320
+ 'use client';
476
321
 
477
- **Features**:
322
+ import { useState } from 'react';
323
+ import {
324
+ address,
325
+ createSolanaRpc,
326
+ pipe,
327
+ createTransactionMessage,
328
+ setTransactionMessageFeePayerSigner,
329
+ setTransactionMessageLifetimeUsingBlockhash,
330
+ appendTransactionMessageInstructions,
331
+ sendAndConfirmTransactionFactory,
332
+ getSignatureFromTransaction,
333
+ signTransactionMessageWithSigners,
334
+ createSolanaRpcSubscriptions,
335
+ lamports,
336
+ assertIsTransactionWithBlockhashLifetime,
337
+ } from '@solana/kit';
338
+ import { getTransferSolInstruction } from '@solana-program/system';
339
+ import { useKitTransactionSigner, useCluster, useConnectorClient, LAMPORTS_PER_SOL } from '@solana/connector';
340
+
341
+ export function ModernSolTransfer() {
342
+ const { signer, ready } = useKitTransactionSigner();
343
+ const { cluster } = useCluster();
344
+ const client = useConnectorClient();
345
+ const [signature, setSignature] = useState<string | null>(null);
478
346
 
479
- - Shows connection status (connected/disconnected/connecting)
480
- - Displays current account and wallet
481
- - Shows active cluster and RPC URL
482
- - Lists detected wallets
483
- - Health check information
484
- - Click to expand/collapse
485
- - Automatically excluded in production builds
347
+ async function handleTransfer(recipientAddress: string, amount: number) {
348
+ if (!signer || !client) {
349
+ throw new Error('Wallet not connected');
350
+ }
486
351
 
487
- **Custom positioning**:
352
+ // Get RPC URL from connector client
353
+ const rpcUrl = client.getRpcUrl();
354
+ if (!rpcUrl) {
355
+ throw new Error('No RPC endpoint configured');
356
+ }
488
357
 
489
- ```typescript
490
- <ConnectorDebugPanel
491
- position="top-left" // 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'
492
- defaultOpen={true}
493
- zIndex={10000}
494
- />
495
- ```
358
+ // Create RPC client using web3.js 2.0
359
+ const rpc = createSolanaRpc(rpcUrl);
360
+ const rpcSubscriptions = createSolanaRpcSubscriptions(rpcUrl.replace('http', 'ws'));
496
361
 
497
- ### Connection Pooling
362
+ // Get recent blockhash
363
+ const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
498
364
 
499
- Reusable RPC connections for better performance.
365
+ // Convert SOL to lamports
366
+ const amountInLamports = lamports(BigInt(Math.floor(amount * Number(LAMPORTS_PER_SOL))));
500
367
 
501
- ```typescript
502
- import { ConnectionPool, createConnectionPool } from '@solana/connector/headless';
503
- import { Connection } from '@solana/web3.js';
504
-
505
- // Create custom pool
506
- const pool = createConnectionPool({
507
- maxSize: 10,
508
- createConnection: cluster => {
509
- return new Connection(cluster.endpoint, {
510
- commitment: 'confirmed',
368
+ // Create transfer instruction
369
+ const transferInstruction = getTransferSolInstruction({
370
+ source: signer,
371
+ destination: address(recipientAddress),
372
+ amount: amountInLamports,
511
373
  });
512
- },
513
- });
514
-
515
- // Get or create connection for a cluster
516
- const connection = pool.get(currentCluster);
517
- const balance = await connection.getBalance(publicKey);
518
374
 
519
- // Clear specific connection when settings change
520
- pool.clear('solana:mainnet');
375
+ // Build transaction message
376
+ const transactionMessage = pipe(
377
+ createTransactionMessage({ version: 0 }),
378
+ tx => setTransactionMessageFeePayerSigner(signer, tx),
379
+ tx => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
380
+ tx => appendTransactionMessageInstructions([transferInstruction], tx),
381
+ );
521
382
 
522
- // Get pool statistics
523
- const stats = pool.getStats();
524
- console.log(`Pool: ${stats.size}/${stats.maxSize}`);
525
- console.log(`Hit rate: ${(stats.hits / (stats.hits + stats.misses)) * 100}%`);
526
- ```
383
+ // Sign transaction
384
+ const signedTransaction = await signTransactionMessageWithSigners(transactionMessage);
527
385
 
528
- **Global pool** (simpler):
386
+ // Send and confirm
387
+ assertIsTransactionWithBlockhashLifetime(signedTransaction);
388
+ await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(signedTransaction, {
389
+ commitment: 'confirmed',
390
+ });
529
391
 
530
- ```typescript
531
- import { getConnectionPool } from '@solana/connector/headless';
392
+ const transactionSignature = getSignatureFromTransaction(signedTransaction);
393
+ setSignature(transactionSignature);
394
+ }
532
395
 
533
- const pool = getConnectionPool();
534
- const connection = pool.get(cluster);
396
+ return (
397
+ <div>
398
+ {/* Your form UI */}
399
+ <button onClick={() => handleTransfer('...', 0.1)} disabled={!ready}>
400
+ Send SOL
401
+ </button>
402
+ {signature && <div>Transaction: {signature}</div>}
403
+ </div>
404
+ );
405
+ }
535
406
  ```
536
407
 
537
- ### Health Checks
408
+ ### Legacy API (`@solana/web3.js`)
538
409
 
539
- Comprehensive diagnostics for debugging and monitoring.
410
+ Use `useTransactionSigner()` for legacy web3.js compatibility:
540
411
 
541
412
  ```typescript
542
- import { useConnectorClient } from '@solana/connector';
413
+ import { useTransactionSigner } from '@solana/connector';
414
+ import { Transaction, SystemProgram } from '@solana/web3.js';
543
415
 
544
- function HealthMonitor() {
545
- const client = useConnectorClient();
416
+ function SendTransaction() {
417
+ const { signer, ready } = useTransactionSigner();
546
418
 
547
- if (!client) return null;
419
+ const handleSend = async () => {
420
+ if (!signer) return;
548
421
 
549
- const health = client.getHealth();
422
+ const transaction = new Transaction().add(
423
+ SystemProgram.transfer({
424
+ fromPubkey: signer.address,
425
+ toPubkey: recipientPubkey,
426
+ lamports: 1000000,
427
+ })
428
+ );
550
429
 
551
- return (
552
- <div>
553
- <h3>Connector Health</h3>
554
- <div>Initialized: {health.initialized ? '✓' : '✗'}</div>
555
- <div>Wallet Standard: {health.walletStandardAvailable ? '✓' : '✗'}</div>
556
- <div>Storage: {health.storageAvailable ? '✓' : '✗'}</div>
557
- <div>Wallets Detected: {health.walletsDetected}</div>
430
+ const signature = await signer.signAndSendTransaction(transaction);
431
+ console.log('Transaction sent:', signature);
432
+ };
558
433
 
559
- {health.errors.length > 0 && (
560
- <div className="errors">
561
- {health.errors.map(err => <div key={err}>{err}</div>)}
562
- </div>
563
- )}
564
- </div>
565
- );
434
+ return <button onClick={handleSend} disabled={!ready}>Send</button>;
566
435
  }
567
436
  ```
568
437
 
569
- ### Wallet Adapter Compatibility
438
+ ---
570
439
 
571
- Drop-in replacement for libraries expecting @solana/wallet-adapter.
440
+ ## UI Elements
572
441
 
573
- ```typescript
574
- import { useTransactionSigner, useConnector } from '@solana/connector';
575
- import { createWalletAdapterCompat } from '@solana/connector/compat';
442
+ ConnectorKit provides composable UI elements that handle data fetching and state management for you. Use the render prop pattern to customize the UI.
576
443
 
577
- function JupiterIntegration() {
578
- const { signer } = useTransactionSigner();
579
- const { disconnect } = useConnector();
444
+ ### Available Elements
580
445
 
581
- // Create wallet-adapter compatible interface
582
- const walletAdapter = createWalletAdapterCompat(signer, {
583
- disconnect: async () => {
584
- await disconnect();
585
- },
586
- onError: (error, operation) => {
587
- console.error(`Wallet adapter error in ${operation}:`, error);
588
- }
589
- });
446
+ - `BalanceElement` - Display SOL balance with refresh
447
+ - `ClusterElement` - Network/cluster selector
448
+ - `TokenListElement` - List of SPL tokens
449
+ - `TransactionHistoryElement` - Recent transaction history
450
+ - `DisconnectElement` - Disconnect button
451
+ - `AccountElement` - Account display and switcher
452
+ - `WalletListElement` - List of available wallets
590
453
 
591
- // Use with Jupiter, Serum, or any wallet-adapter library
592
- return <JupiterTerminal wallet={walletAdapter} />;
593
- }
594
- ```
454
+ ### Example: Wallet Dropdown
595
455
 
596
- **Compatible with**:
456
+ ```typescript
457
+ 'use client';
597
458
 
598
- - Jupiter Aggregator
599
- - Serum DEX
600
- - Raydium
601
- - Marinade Finance
602
- - Any library expecting @solana/wallet-adapter
459
+ import {
460
+ BalanceElement,
461
+ ClusterElement,
462
+ TokenListElement,
463
+ TransactionHistoryElement,
464
+ DisconnectElement,
465
+ } from '@solana/connector/react';
466
+
467
+ export function WalletDropdown() {
468
+ return (
469
+ <div className="wallet-dropdown">
470
+ {/* Balance */}
471
+ <BalanceElement
472
+ render={({ solBalance, isLoading, refetch }) => (
473
+ <div>
474
+ <div>Balance: {isLoading ? '...' : `${solBalance?.toFixed(4)} SOL`}</div>
475
+ <button onClick={refetch}>Refresh</button>
476
+ </div>
477
+ )}
478
+ />
479
+
480
+ {/* Network Selector */}
481
+ <ClusterElement
482
+ render={({ cluster, clusters, setCluster }) => (
483
+ <select value={cluster?.id} onChange={e => setCluster(e.target.value)}>
484
+ {clusters.map(c => (
485
+ <option key={c.id} value={c.id}>
486
+ {c.label}
487
+ </option>
488
+ ))}
489
+ </select>
490
+ )}
491
+ />
492
+
493
+ {/* Tokens */}
494
+ <TokenListElement
495
+ limit={5}
496
+ render={({ tokens, isLoading }) => (
497
+ <div>
498
+ {isLoading ? (
499
+ <div>Loading tokens...</div>
500
+ ) : (
501
+ tokens.map(token => (
502
+ <div key={token.mint}>
503
+ {token.symbol}: {token.formatted}
504
+ </div>
505
+ ))
506
+ )}
507
+ </div>
508
+ )}
509
+ />
510
+
511
+ {/* Transaction History */}
512
+ <TransactionHistoryElement
513
+ limit={5}
514
+ render={({ transactions, isLoading }) => (
515
+ <div>
516
+ {isLoading ? (
517
+ <div>Loading transactions...</div>
518
+ ) : (
519
+ transactions.map(tx => (
520
+ <a key={tx.signature} href={tx.explorerUrl} target="_blank">
521
+ {tx.type} - {tx.formattedTime}
522
+ </a>
523
+ ))
524
+ )}
525
+ </div>
526
+ )}
527
+ />
528
+
529
+ {/* Disconnect */}
530
+ <DisconnectElement
531
+ render={({ disconnect, disconnecting }) => (
532
+ <button onClick={disconnect} disabled={disconnecting}>
533
+ {disconnecting ? 'Disconnecting...' : 'Disconnect'}
534
+ </button>
535
+ )}
536
+ />
537
+ </div>
538
+ );
539
+ }
540
+ ```
603
541
 
604
542
  ---
605
543
 
@@ -612,16 +550,11 @@ import { getDefaultConfig } from '@solana/connector';
612
550
 
613
551
  const config = getDefaultConfig({
614
552
  appName: 'My App', // Required
553
+ appUrl: 'https://myapp.com', // Optional: for mobile wallet adapter
615
554
  autoConnect: true, // Auto-reconnect (default: true)
616
- network: 'mainnet-beta', // Initial network
555
+ network: 'mainnet-beta', // Initial network (default: 'mainnet-beta')
617
556
  enableMobile: true, // Mobile Wallet Adapter (default: true)
618
557
  debug: false, // Debug logging
619
-
620
- // NEW: Custom error handler
621
- onError: (error, errorInfo) => {
622
- console.error('Connector error:', error);
623
- errorTracker.captureException(error, errorInfo);
624
- },
625
558
  });
626
559
  ```
627
560
 
@@ -634,20 +567,26 @@ const config = getDefaultConfig({
634
567
  });
635
568
  ```
636
569
 
637
- ### Custom Clusters
570
+ ### Custom RPC Endpoints
638
571
 
639
572
  ```typescript
640
- import { getDefaultConfig, createSolanaMainnet } from '@solana/connector';
573
+ import { getDefaultConfig } from '@solana/connector';
641
574
 
642
575
  const config = getDefaultConfig({
643
576
  appName: 'My App',
644
577
  clusters: [
645
- createSolanaMainnet({
646
- endpoint: 'https://my-custom-rpc.com',
647
- }),
648
- ],
649
- customClusters: [
650
- // Add additional custom clusters
578
+ {
579
+ id: 'solana:mainnet' as const,
580
+ label: 'Mainnet (Custom RPC)',
581
+ name: 'mainnet-beta' as const,
582
+ url: 'https://my-custom-rpc.com',
583
+ },
584
+ {
585
+ id: 'solana:devnet' as const,
586
+ label: 'Devnet',
587
+ name: 'devnet' as const,
588
+ url: 'https://api.devnet.solana.com',
589
+ },
651
590
  ],
652
591
  });
653
592
  ```
@@ -655,18 +594,16 @@ const config = getDefaultConfig({
655
594
  ### Mobile Wallet Adapter
656
595
 
657
596
  ```typescript
658
- <ConnectorProvider
659
- config={config}
660
- mobile={{
661
- appIdentity: {
662
- name: 'My App',
663
- uri: 'https://myapp.com',
664
- icon: 'https://myapp.com/icon.png'
665
- }
666
- }}
667
- >
668
- <App />
669
- </ConnectorProvider>
597
+ import { getDefaultMobileConfig } from '@solana/connector/headless';
598
+
599
+ const mobile = getDefaultMobileConfig({
600
+ appName: 'My App',
601
+ appUrl: 'https://myapp.com',
602
+ });
603
+
604
+ <AppProvider connectorConfig={config} mobile={mobile}>
605
+ {children}
606
+ </AppProvider>
670
607
  ```
671
608
 
672
609
  ---
@@ -675,7 +612,7 @@ const config = getDefaultConfig({
675
612
 
676
613
  ### Headless Client (Vue, Svelte, Vanilla JS)
677
614
 
678
- Use `ConnectorClient` for non-React frameworks.
615
+ Use `ConnectorClient` for non-React frameworks:
679
616
 
680
617
  ```typescript
681
618
  import { ConnectorClient, getDefaultConfig } from '@solana/connector/headless';
@@ -695,15 +632,6 @@ const unsubscribe = client.subscribe(state => {
695
632
  console.log('State updated:', state);
696
633
  });
697
634
 
698
- // Subscribe to events (NEW!)
699
- const unsubEvents = client.on(event => {
700
- console.log('Event:', event.type, event);
701
- });
702
-
703
- // Check health (NEW!)
704
- const health = client.getHealth();
705
- console.log('Health:', health);
706
-
707
635
  // Disconnect
708
636
  await client.disconnect();
709
637
 
@@ -711,44 +639,15 @@ await client.disconnect();
711
639
  client.destroy();
712
640
  ```
713
641
 
714
- ### Unified Config (Armadura Integration)
715
-
716
- If you're using both ConnectorKit and Armadura:
717
-
718
- ```typescript
719
- import { createConfig, AppProvider } from '@solana/connector';
720
- import { ArmaProvider } from '@armadura/sdk';
721
-
722
- const config = createConfig({
723
- appName: 'My App',
724
- network: 'mainnet',
725
- rpcUrl: 'https://my-custom-rpc.com',
726
- autoConnect: true
727
- });
728
-
729
- function App() {
730
- return (
731
- <AppProvider config={config.connectorConfig}>
732
- <ArmaProvider
733
- config={{
734
- network: config.network,
735
- rpcUrl: config.rpcUrl,
736
- providers: [/* ... */]
737
- }}
738
- useConnector="auto"
739
- >
740
- {children}
741
- </ArmaProvider>
742
- </AppProvider>
743
- );
744
- }
745
- ```
642
+ ### Custom Storage (React Native, SSR)
746
643
 
747
- ### Custom Storage
644
+ Storage uses nanostores with built-in enhancements that are **automatically applied**:
748
645
 
749
- **Most users don't need to configure storage** - it works automatically with validation, error handling, and SSR fallback.
646
+ - Validation (Solana address format checking)
647
+ - Error handling (catches localStorage quota errors, private browsing)
648
+ - SSR fallback (uses memory storage when localStorage unavailable)
750
649
 
751
- Only customize for:
650
+ **Most users don't need to configure storage.** Only customize for:
752
651
 
753
652
  - React Native (custom storage backend)
754
653
  - Additional validation rules
@@ -759,7 +658,6 @@ import { getDefaultConfig, createEnhancedStorageWallet, EnhancedStorageAdapter }
759
658
 
760
659
  const config = getDefaultConfig({
761
660
  appName: 'My App',
762
-
763
661
  storage: {
764
662
  wallet: new EnhancedStorageAdapter(
765
663
  createEnhancedStorageWallet({
@@ -768,11 +666,11 @@ const config = getDefaultConfig({
768
666
  return walletName !== null && walletName.length > 0;
769
667
  },
770
668
  onError: error => {
669
+ // Custom error tracking
771
670
  Sentry.captureException(error);
772
671
  },
773
672
  }),
774
673
  ),
775
- // account and cluster use defaults if not specified
776
674
  },
777
675
  });
778
676
  ```
@@ -785,7 +683,7 @@ const config = getDefaultConfig({
785
683
 
786
684
  ```typescript
787
685
  // Full library - includes React and headless
788
- import { ConnectorProvider, useConnector } from '@solana/connector';
686
+ import { ConnectorProvider, useConnector, useAccount } from '@solana/connector';
789
687
  ```
790
688
 
791
689
  ### Headless Export (Framework Agnostic)
@@ -802,427 +700,58 @@ import { ConnectorClient, getDefaultConfig } from '@solana/connector/headless';
802
700
  import { useConnector, useAccount } from '@solana/connector/react';
803
701
  ```
804
702
 
805
- ### Compatibility Layer (NEW!)
806
-
807
- ```typescript
808
- // Wallet adapter compatibility bridge
809
- import { createWalletAdapterCompat } from '@solana/connector/compat';
810
- ```
811
-
812
703
  ---
813
704
 
814
- ## Testing
815
-
816
- The connector package includes a comprehensive test suite built with Vitest. All tests are located in `src/__tests__/` and co-located with source files.
817
-
818
- ### Running Tests
819
-
820
- ```bash
821
- # Run all tests
822
- pnpm test
823
-
824
- # Run tests in watch mode
825
- pnpm test:watch
826
-
827
- # Run tests with UI
828
- pnpm test:ui
829
-
830
- # Generate coverage report
831
- pnpm test:coverage
832
- ```
833
-
834
- ### Test Coverage
835
-
836
- The package maintains high test coverage:
837
-
838
- - **Lines**: 80%+
839
- - **Functions**: 80%+
840
- - **Branches**: 75%+
841
- - **Statements**: 80%+
842
-
843
- ### Test Structure
844
-
845
- ```
846
- src/
847
- ├── lib/
848
- │ ├── core/
849
- │ │ ├── state-manager.ts
850
- │ │ └── state-manager.test.ts # Unit tests
851
- │ └── connection/
852
- │ ├── connection-manager.ts
853
- │ └── connection-manager.test.ts # Unit tests
854
- ├── hooks/
855
- │ ├── use-account.ts
856
- │ └── use-account.test.tsx # React hook tests
857
- └── __tests__/
858
- ├── setup.ts # Global test setup
859
- ├── mocks/ # Mock implementations
860
- │ ├── wallet-standard-mock.ts # Mock wallets
861
- │ ├── storage-mock.ts # Mock storage
862
- │ └── window-mock.ts # Mock browser APIs
863
- ├── fixtures/ # Test data
864
- │ ├── wallets.ts # Wallet fixtures
865
- │ ├── accounts.ts # Account fixtures
866
- │ └── transactions.ts # Transaction fixtures
867
- ├── utils/ # Test helpers
868
- │ ├── test-helpers.ts # Common utilities
869
- │ ├── react-helpers.tsx # React test utils
870
- │ └── wait-for-state.ts # State helpers
871
- └── integration/ # Integration tests
872
- └── connector-flow.test.ts # Full workflows
873
- ```
874
-
875
- ### Writing Tests
876
-
877
- Example unit test:
878
-
879
- ```typescript
880
- import { describe, it, expect } from 'vitest';
881
- import { StateManager } from './state-manager';
882
-
883
- describe('StateManager', () => {
884
- it('should update state correctly', () => {
885
- const manager = new StateManager(initialState);
886
- manager.updateState({ connected: true });
887
-
888
- expect(manager.getSnapshot().connected).toBe(true);
889
- });
890
- });
891
- ```
892
-
893
- Example React hook test:
894
-
895
- ```typescript
896
- import { renderHook } from '@testing-library/react';
897
- import { useAccount } from './use-account';
898
- import { createHookWrapper } from '../__tests__/utils/react-helpers';
899
-
900
- describe('useAccount', () => {
901
- it('should return account information', () => {
902
- const { result } = renderHook(() => useAccount(), {
903
- wrapper: createHookWrapper(),
904
- });
905
-
906
- expect(result.current.address).toBeDefined();
907
- });
908
- });
909
- ```
910
-
911
- ### Test Utilities
912
-
913
- The package provides comprehensive test utilities:
914
-
915
- **Mock Wallets:**
916
-
917
- ```typescript
918
- import { createMockPhantomWallet, createMockSolflareWallet } from '../mocks/wallet-standard-mock';
919
-
920
- const wallet = createMockPhantomWallet({
921
- connectBehavior: 'success', // or 'error', 'timeout'
922
- });
923
- ```
924
-
925
- **Test Fixtures:**
926
-
927
- ```typescript
928
- import { createTestAccounts, TEST_ADDRESSES } from '../fixtures/accounts';
929
- import { createTestWallets } from '../fixtures/wallets';
930
-
931
- const accounts = createTestAccounts(3);
932
- const wallets = createTestWallets();
933
- ```
934
-
935
- **Test Helpers:**
936
-
937
- ```typescript
938
- import { waitForCondition, createEventCollector } from '../utils/test-helpers';
939
-
940
- // Wait for a condition
941
- await waitForCondition(() => state.connected, { timeout: 5000 });
942
-
943
- // Collect events
944
- const collector = createEventCollector();
945
- client.on(collector.collect);
946
- collector.assertEventEmitted('connected');
947
- ```
705
+ ## API Reference
948
706
 
949
- ### Contributing Tests
707
+ ### Hooks
950
708
 
951
- All new features and bug fixes should include tests:
952
-
953
- 1. Create test file next to source file with `.test.ts` or `.test.tsx` extension
954
- 2. Follow existing patterns in similar test files
955
- 3. Ensure tests pass locally before submitting
956
- 4. Maintain or improve coverage percentage
957
-
958
- For detailed testing guidelines, see [Testing Guide](src/__tests__/README.md).
959
-
960
- ---
961
-
962
- ## Complete API Reference
709
+ | Hook | Description | Returns |
710
+ |------|-------------|---------|
711
+ | `useConnector()` | Main wallet connection hook | `{ wallets, selectedWallet, accounts, connected, connecting, select, disconnect }` |
712
+ | `useAccount()` | Account management hook | `{ address, formatted, copy, copied, accounts, selectAccount }` |
713
+ | `useCluster()` | Network/cluster management hook | `{ cluster, clusters, setCluster, isMainnet, isDevnet, rpcUrl }` |
714
+ | `useWalletInfo()` | Wallet metadata hook | `{ name, icon, wallet, connecting }` |
715
+ | `useTransactionSigner()` | Legacy transaction signer (web3.js) | `{ signer, ready, address, capabilities }` |
716
+ | `useKitTransactionSigner()` | Modern transaction signer (@solana/kit) | `{ signer, ready, address }` |
717
+ | `useBalance()` | SOL balance hook | `{ solBalance, isLoading, refetch }` |
718
+ | `useTokens()` | SPL tokens hook | `{ tokens, isLoading, refetch }` |
719
+ | `useTransactions()` | Transaction history hook | `{ transactions, isLoading, refetch }` |
963
720
 
964
721
  ### Configuration Functions
965
722
 
966
- #### `getDefaultConfig(options)`
967
-
968
- ```typescript
969
- const config = getDefaultConfig({
970
- appName: string, // Required: App name
971
- appUrl?: string, // App URL for metadata
972
- autoConnect?: boolean, // Auto-reconnect (default: true)
973
- debug?: boolean, // Debug logging
974
- network?: 'mainnet' | 'mainnet-beta' // Initial network (default: mainnet-beta)
975
- | 'devnet' | 'testnet' | 'localnet',
976
- enableMobile?: boolean, // Mobile Wallet Adapter (default: true)
977
- storage?: ConnectorConfig['storage'], // Custom storage adapters
978
- clusters?: SolanaCluster[], // Override default clusters
979
- customClusters?: SolanaCluster[], // Add custom clusters
980
- persistClusterSelection?: boolean, // Persist cluster (default: true)
981
- enableErrorBoundary?: boolean, // Error boundaries (default: true)
982
- maxRetries?: number, // Retry attempts (default: 3)
983
- onError?: (error, errorInfo) => void // Error handler (NEW!)
984
- });
985
- ```
986
-
987
- ### Transaction Signing API (NEW!)
988
-
989
- #### `useTransactionSigner()`
990
-
991
- React hook for transaction operations.
992
-
993
- ```typescript
994
- interface UseTransactionSignerReturn {
995
- signer: TransactionSigner | null; // Signer instance
996
- ready: boolean; // Whether signer is ready
997
- address: string | null; // Current address
998
- capabilities: TransactionSignerCapabilities; // What signer can do
999
- }
1000
- ```
1001
-
1002
- #### `createTransactionSigner(config)`
1003
-
1004
- Create a transaction signer (headless).
1005
-
1006
- ```typescript
1007
- import { createTransactionSigner } from '@solana/connector/headless';
1008
-
1009
- const signer = createTransactionSigner({
1010
- wallet: connectedWallet,
1011
- account: selectedAccount,
1012
- cluster: currentCluster, // Optional
1013
- });
1014
- ```
1015
-
1016
- #### `TransactionSigner` Interface
1017
-
1018
- ```typescript
1019
- interface TransactionSigner {
1020
- readonly address: string;
1021
-
1022
- signTransaction(tx: any): Promise<any>;
1023
- signAllTransactions(txs: any[]): Promise<any[]>;
1024
- signAndSendTransaction(tx: any, options?: SendOptions): Promise<string>;
1025
- signAndSendTransactions(txs: any[], options?: SendOptions): Promise<string[]>;
1026
- signMessage?(message: Uint8Array): Promise<Uint8Array>;
1027
-
1028
- getCapabilities(): TransactionSignerCapabilities;
1029
- }
1030
- ```
1031
-
1032
- ### Event System API (NEW!)
1033
-
1034
- #### Event Types
1035
-
1036
- ```typescript
1037
- type ConnectorEvent =
1038
- | { type: 'wallet:connected'; wallet: string; account: string; timestamp: string }
1039
- | { type: 'wallet:disconnected'; timestamp: string }
1040
- | { type: 'cluster:changed'; cluster: string; previousCluster: string | null; timestamp: string }
1041
- | { type: 'wallets:detected'; count: number; timestamp: string }
1042
- | { type: 'connecting'; wallet: string; timestamp: string }
1043
- | { type: 'connection:failed'; wallet: string; error: string; timestamp: string }
1044
- | { type: 'error'; error: Error; context: string; timestamp: string };
1045
- ```
1046
-
1047
- #### Methods
1048
-
1049
- ```typescript
1050
- // Subscribe to events
1051
- const unsubscribe = client.on(event => {
1052
- console.log('Event:', event.type, event);
1053
- });
1054
-
1055
- // Unsubscribe
1056
- client.off(listener);
1057
-
1058
- // Unsubscribe all
1059
- client.offAll();
1060
- ```
1061
-
1062
- ### Health Check API (NEW!)
1063
-
1064
- ```typescript
1065
- interface ConnectorHealth {
1066
- initialized: boolean;
1067
- walletStandardAvailable: boolean;
1068
- storageAvailable: boolean;
1069
- walletsDetected: number;
1070
- errors: string[];
1071
- connectionState: {
1072
- connected: boolean;
1073
- connecting: boolean;
1074
- hasSelectedWallet: boolean;
1075
- hasSelectedAccount: boolean;
1076
- };
1077
- timestamp: string;
1078
- }
1079
-
1080
- // Get health status
1081
- const health = client.getHealth();
1082
- ```
1083
-
1084
- ### Connection Pool API (NEW!)
1085
-
1086
- ```typescript
1087
- class ConnectionPool {
1088
- get(cluster: SolanaCluster): ConnectionLike;
1089
- has(clusterId: string): boolean;
1090
- clear(clusterId: string): void;
1091
- clearAll(): void;
1092
- getStats(): ConnectionPoolStats;
1093
- resetStats(): void;
1094
- }
1095
-
1096
- // Create pool
1097
- const pool = createConnectionPool(options);
1098
-
1099
- // Get global pool
1100
- const pool = getConnectionPool();
1101
- ```
1102
-
1103
- ### Wallet Adapter Compat API (NEW!)
1104
-
1105
- ```typescript
1106
- // Create wallet-adapter compatible interface
1107
- createWalletAdapterCompat(
1108
- signer: TransactionSigner | null,
1109
- options: {
1110
- disconnect: () => Promise<void>;
1111
- transformTransaction?: (tx: any) => any;
1112
- onError?: (error: Error, operation: string) => void;
1113
- }
1114
- ): WalletAdapterCompatible
1115
-
1116
- // React hook version
1117
- useWalletAdapterCompat(
1118
- signer: TransactionSigner | null,
1119
- disconnect: () => Promise<void>,
1120
- options?: Omit<WalletAdapterCompatOptions, 'disconnect'>
1121
- ): WalletAdapterCompatible
1122
-
1123
- // Type guard
1124
- isWalletAdapterCompatible(obj: any): obj is WalletAdapterCompatible
1125
- ```
1126
-
1127
- ### Polyfill API (NEW!)
1128
-
1129
- ```typescript
1130
- import {
1131
- installPolyfills,
1132
- isPolyfillInstalled,
1133
- isCryptoAvailable,
1134
- getPolyfillStatus,
1135
- } from '@solana/connector/headless';
1136
-
1137
- // Install browser polyfills (automatic in React provider)
1138
- installPolyfills();
1139
-
1140
- // Check status
1141
- const installed = isPolyfillInstalled();
1142
- const cryptoAvailable = isCryptoAvailable();
1143
- const status = getPolyfillStatus();
1144
- ```
723
+ | Function | Description |
724
+ |----------|-------------|
725
+ | `getDefaultConfig(options)` | Create default connector configuration |
726
+ | `getDefaultMobileConfig(options)` | Create mobile wallet adapter configuration |
727
+ | `createConfig(options)` | Create unified config for ConnectorKit + Armadura |
1145
728
 
1146
729
  ### Utility Functions
1147
730
 
1148
- #### Formatting
1149
-
1150
- ```typescript
1151
- import { formatSOL, formatAddress } from '@solana/connector';
1152
-
1153
- // Format SOL amounts
1154
- formatSOL(1500000000, { decimals: 4 }); // "1.5000 SOL"
1155
-
1156
- // Format addresses
1157
- formatAddress(address, { length: 6 }); // "5Gv8yU...8x3kF"
1158
-
1159
- // Lightweight versions (smaller bundle, no Intl)
1160
- import { formatSOLSimple, formatAddressSimple } from '@solana/connector';
1161
- ```
1162
-
1163
- #### Clipboard
1164
-
1165
- ```typescript
1166
- import { copyAddressToClipboard, copyToClipboard } from '@solana/connector';
1167
-
1168
- await copyAddressToClipboard(address);
1169
- await copyToClipboard(text);
1170
- ```
1171
-
1172
- #### Cluster Utilities
731
+ | Function | Description |
732
+ |----------|-------------|
733
+ | `formatAddress(address, options?)` | Format Solana address |
734
+ | `formatSOL(lamports, options?)` | Format SOL amount |
735
+ | `copyAddressToClipboard(address)` | Copy address to clipboard |
736
+ | `getTransactionUrl(cluster, signature)` | Get Solana Explorer transaction URL |
737
+ | `getAddressUrl(cluster, address)` | Get Solana Explorer address URL |
1173
738
 
1174
- ```typescript
1175
- import {
1176
- getClusterRpcUrl,
1177
- getClusterExplorerUrl,
1178
- getTransactionUrl,
1179
- getAddressUrl,
1180
- isMainnetCluster,
1181
- isDevnetCluster,
1182
- } from '@solana/connector';
1183
-
1184
- const rpcUrl = getClusterRpcUrl(cluster);
1185
- const explorerUrl = getClusterExplorerUrl(cluster);
1186
- const txUrl = getTransactionUrl(cluster, signature);
1187
- const addrUrl = getAddressUrl(cluster, address);
1188
- ```
739
+ ---
1189
740
 
1190
- ### Types
741
+ ## Types
1191
742
 
1192
743
  ```typescript
1193
744
  import type {
1194
745
  // Configuration
1195
746
  ConnectorConfig,
1196
747
  DefaultConfigOptions,
1197
- ExtendedConnectorConfig,
1198
748
  UnifiedConfig,
1199
- MobileWalletAdapterConfig,
1200
749
 
1201
750
  // State & Info
1202
751
  ConnectorState,
1203
752
  ConnectorSnapshot,
1204
753
  WalletInfo,
1205
754
  AccountInfo,
1206
- ConnectorHealth, // NEW!
1207
-
1208
- // Events
1209
- ConnectorEvent, // NEW!
1210
- ConnectorEventListener, // NEW!
1211
-
1212
- // Transaction Signing
1213
- TransactionSigner, // NEW!
1214
- TransactionSignerConfig, // NEW!
1215
- TransactionSignerCapabilities, // NEW!
1216
- SignedTransaction, // NEW!
1217
-
1218
- // Connection Pooling
1219
- ConnectionLike, // NEW!
1220
- ConnectionPoolOptions, // NEW!
1221
- ConnectionPoolStats, // NEW!
1222
-
1223
- // Wallet Adapter Compat
1224
- WalletAdapterCompatible, // NEW!
1225
- WalletAdapterCompatOptions, // NEW!
1226
755
 
1227
756
  // Wallet Standard
1228
757
  Wallet,
@@ -1232,101 +761,17 @@ import type {
1232
761
  SolanaCluster,
1233
762
  SolanaClusterId,
1234
763
 
1235
- // Storage
1236
- StorageAdapter,
1237
-
1238
764
  // Hook Returns
1239
765
  UseClusterReturn,
1240
766
  UseAccountReturn,
1241
767
  UseWalletInfoReturn,
1242
- UseTransactionSignerReturn, // NEW!
1243
-
1244
- // Errors
1245
- WalletError,
768
+ UseTransactionSignerReturn,
769
+ UseKitTransactionSignerReturn,
1246
770
  } from '@solana/connector';
1247
771
  ```
1248
772
 
1249
773
  ---
1250
774
 
1251
- ## Performance
1252
-
1253
- ### Bundle Size
1254
-
1255
- | Component | Size (gzipped) | Tree-Shakeable |
1256
- | -------------------- | -------------- | ------------------ |
1257
- | **Base Connector** | ~45KB | ✅ |
1258
- | + Polyfills | +2KB | ❌ (auto-included) |
1259
- | + Transaction Signer | +3KB | ✅ |
1260
- | + Connection Pool | +1.5KB | ✅ |
1261
- | + Debug Panel | +2KB | ✅ (dev-only) |
1262
- | + Event System | +0.5KB | ✅ |
1263
- | + Compat Layer | +2KB | ✅ |
1264
-
1265
- **Total**: ~48-53KB for typical production usage
1266
-
1267
- ### Runtime Performance
1268
-
1269
- - **40-60% fewer re-renders** via optimized state updates
1270
- - **Connection pooling** reduces memory usage and initialization overhead
1271
- - **Automatic tree-shaking** excludes unused features
1272
- - **Debug panel** automatically excluded in production builds
1273
-
1274
- ---
1275
-
1276
- ## Browser Compatibility
1277
-
1278
- Enhanced support for:
1279
-
1280
- - ✅ Chrome/Edge 90+
1281
- - ✅ Firefox 88+
1282
- - ✅ Safari 14+
1283
- - ✅ iOS Safari 14+
1284
- - ✅ Chrome Mobile 90+
1285
- - ✅ Samsung Internet 15+
1286
-
1287
- Automatic polyfills ensure compatibility across all environments.
1288
-
1289
- ---
1290
-
1291
- ## Migration from @solana/wallet-adapter
1292
-
1293
- Using the wallet-adapter compatibility bridge for gradual migration:
1294
-
1295
- ```typescript
1296
- // Before (wallet-adapter)
1297
- import { useWallet } from '@solana/wallet-adapter-react';
1298
-
1299
- const { publicKey, sendTransaction } = useWallet();
1300
- await sendTransaction(tx, connection);
1301
-
1302
- // After (connector-kit)
1303
- import { useTransactionSigner } from '@solana/connector';
1304
-
1305
- const { signer } = useTransactionSigner();
1306
- await signer.signAndSendTransaction(tx);
1307
-
1308
- // Or use compatibility bridge for existing integrations
1309
- import { createWalletAdapterCompat } from '@solana/connector/compat';
1310
-
1311
- const walletAdapter = createWalletAdapterCompat(signer, { disconnect });
1312
- // Pass walletAdapter to existing wallet-adapter code
1313
- ```
1314
-
1315
- ---
1316
-
1317
- ## Examples
1318
-
1319
- Check out the [examples directory](../../examples/react) for:
1320
-
1321
- - **React Example** - Complete wallet connection UI with shadcn/ui
1322
- - **Vite Example** - Lightweight setup with Vite
1323
- - **Transaction Signing** - Full transaction demos
1324
- - **Network Switching** - Cluster/network management
1325
- - **Account Management** - Multi-account support
1326
- - **Mobile Support** - Solana Mobile Wallet Adapter
1327
-
1328
- ---
1329
-
1330
775
  ## Development
1331
776
 
1332
777
  ### Commands
@@ -1353,9 +798,6 @@ pnpm test
1353
798
  # Test in watch mode
1354
799
  pnpm test:watch
1355
800
 
1356
- # Test with UI
1357
- pnpm test:ui
1358
-
1359
801
  # Coverage report
1360
802
  pnpm test:coverage
1361
803
 
@@ -1363,65 +805,17 @@ pnpm test:coverage
1363
805
  pnpm size
1364
806
  ```
1365
807
 
1366
- ### Project Structure
1367
-
1368
- ```
1369
- packages/connector/
1370
- ├── src/
1371
- │ ├── lib/
1372
- │ │ ├── core/ # Core functionality
1373
- │ │ │ ├── state-manager.ts
1374
- │ │ │ ├── event-emitter.ts
1375
- │ │ │ └── debug-metrics.ts
1376
- │ │ ├── connection/ # Connection management
1377
- │ │ │ ├── connection-manager.ts
1378
- │ │ │ └── connection-pool.ts
1379
- │ │ ├── transaction/ # Transaction signing
1380
- │ │ │ ├── transaction-signer.ts
1381
- │ │ │ └── signer-factory.ts
1382
- │ │ └── storage/ # Persistence layer
1383
- │ │ └── enhanced-storage.ts
1384
- │ ├── hooks/ # React hooks
1385
- │ │ ├── use-connector.ts
1386
- │ │ ├── use-account.ts
1387
- │ │ ├── use-cluster.ts
1388
- │ │ └── use-transaction-signer.ts
1389
- │ ├── components/ # React components
1390
- │ │ └── debug-panel.tsx
1391
- │ ├── compat/ # Wallet adapter compatibility
1392
- │ │ └── wallet-adapter-compat.ts
1393
- │ ├── __tests__/ # Test utilities
1394
- │ │ ├── mocks/
1395
- │ │ ├── fixtures/
1396
- │ │ └── utils/
1397
- │ └── index.ts # Main exports
1398
- ├── tsconfig.json
1399
- ├── tsup.config.ts
1400
- ├── vitest.config.ts
1401
- └── package.json
1402
- ```
1403
-
1404
- ### Contributing
1405
-
1406
- Contributions are welcome! Please:
1407
-
1408
- 1. Fork the repository
1409
- 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
1410
- 3. Make your changes
1411
- 4. Add tests for new functionality
1412
- 5. Ensure tests pass (`pnpm test`)
1413
- 6. Commit with conventional commits (`feat:`, `fix:`, `docs:`, etc.)
1414
- 7. Push to your fork and submit a pull request
1415
-
1416
- For detailed testing guidelines, see [Testing Guide](src/__tests__/README.md).
1417
-
1418
808
  ---
1419
809
 
1420
- ## Community & Support
810
+ ## Examples
811
+
812
+ Check out the [examples directory](../../examples/next-js) for complete working examples:
1421
813
 
1422
- - **Questions?** Ask on [Solana Stack Exchange](https://solana.stackexchange.com/) (use the `connectorkit` tag)
1423
- - **Issues?** Report on [GitHub Issues](https://github.com/your-org/connectorkit/issues)
1424
- - **Discussions?** Join [GitHub Discussions](https://github.com/your-org/connectorkit/discussions)
814
+ - **Next.js Example** - Full-featured wallet connection UI with shadcn/ui
815
+ - **Transaction Signing** - Modern and legacy transaction examples
816
+ - **Network Switching** - Cluster/network management
817
+ - **Account Management** - Multi-account support
818
+ - **Mobile Support** - Solana Mobile Wallet Adapter
1425
819
 
1426
820
  ---
1427
821
 
@@ -1439,22 +833,6 @@ Compatible with all [Wallet Standard](https://github.com/wallet-standard/wallet-
1439
833
 
1440
834
  ---
1441
835
 
1442
- ## Other Resources
1443
-
1444
- - [ConnectorKit Documentation](https://connectorkit.dev) - Full documentation site
1445
- - [API Reference](#complete-api-reference) - Complete TypeScript API
1446
- - [Examples](../../examples/react) - Working examples
1447
- - [Wallet Standard Spec](https://github.com/wallet-standard/wallet-standard) - Protocol specification
1448
- - [@solana/connector on NPM](https://www.npmjs.com/package/@solana/connector) - Package page
1449
-
1450
- ---
1451
-
1452
- ## Source
1453
-
1454
- - [GitHub Repository](https://github.com/your-org/connectorkit)
1455
- - [Examples Directory](../../examples)
1456
- - [Package Directory](../../packages/connector)
1457
-
1458
- Built with ❤️ for the Solana ecosystem.
836
+ ## License
1459
837
 
1460
- Licensed under MIT. See [LICENSE](../../LICENSE) for details.
838
+ MIT