@solana/connector 0.1.9 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +403 -50
- package/dist/chunk-4KD6HQQG.js +69 -0
- package/dist/chunk-4KD6HQQG.js.map +1 -0
- package/dist/chunk-BJAVJQLK.js +230 -0
- package/dist/chunk-BJAVJQLK.js.map +1 -0
- package/dist/{chunk-5HRJKCIL.js → chunk-BZ2VBJCZ.js} +1061 -424
- package/dist/chunk-BZ2VBJCZ.js.map +1 -0
- package/dist/{chunk-WDXEP4AJ.js → chunk-EM4KNOKG.js} +658 -190
- package/dist/chunk-EM4KNOKG.js.map +1 -0
- package/dist/chunk-HN5AJF7F.js +507 -0
- package/dist/chunk-HN5AJF7F.js.map +1 -0
- package/dist/chunk-HO6QNKFM.mjs +61 -0
- package/dist/chunk-HO6QNKFM.mjs.map +1 -0
- package/dist/chunk-HPQ5T32K.mjs +178 -0
- package/dist/chunk-HPQ5T32K.mjs.map +1 -0
- package/dist/{chunk-MAXA3HEP.mjs → chunk-IDTUFDNB.mjs} +962 -344
- package/dist/chunk-IDTUFDNB.mjs.map +1 -0
- package/dist/{chunk-P5LXUDP6.mjs → chunk-RTXUS5KG.mjs} +579 -119
- package/dist/chunk-RTXUS5KG.mjs.map +1 -0
- package/dist/{chunk-DSUCH44G.js → chunk-SITQ4JWM.js} +23 -67
- package/dist/chunk-SITQ4JWM.js.map +1 -0
- package/dist/chunk-UCISIAOG.mjs +501 -0
- package/dist/chunk-UCISIAOG.mjs.map +1 -0
- package/dist/{chunk-J7DHGLW6.mjs → chunk-ZZTY3O4N.mjs} +21 -61
- package/dist/chunk-ZZTY3O4N.mjs.map +1 -0
- package/dist/compat.d.mts +1 -1
- package/dist/compat.d.ts +1 -1
- package/dist/compat.js +10 -9
- package/dist/compat.js.map +1 -1
- package/dist/compat.mjs +2 -1
- package/dist/compat.mjs.map +1 -1
- package/dist/headless.d.mts +239 -104
- package/dist/headless.d.ts +239 -104
- package/dist/headless.js +255 -169
- package/dist/headless.mjs +5 -3
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +316 -206
- package/dist/index.mjs +6 -4
- package/dist/react.d.mts +299 -9
- package/dist/react.d.ts +299 -9
- package/dist/react.js +90 -38
- package/dist/react.mjs +2 -2
- package/dist/{standard-shim-CT49DM5l.d.mts → standard-shim-CGB88PPO.d.mts} +673 -52
- package/dist/{standard-shim-D9guL5fz.d.ts → standard-shim-tmnQelaJ.d.ts} +673 -52
- package/dist/{transaction-signer-T-KVQFi8.d.mts → transaction-signer-7NaYmP5w.d.mts} +1 -0
- package/dist/{transaction-signer-T-KVQFi8.d.ts → transaction-signer-7NaYmP5w.d.ts} +1 -0
- package/dist/walletconnect-447EY3OJ.js +28 -0
- package/dist/walletconnect-447EY3OJ.js.map +1 -0
- package/dist/walletconnect-U455PO4I.mjs +3 -0
- package/dist/walletconnect-U455PO4I.mjs.map +1 -0
- package/package.json +6 -2
- package/dist/chunk-5HRJKCIL.js.map +0 -1
- package/dist/chunk-DSUCH44G.js.map +0 -1
- package/dist/chunk-I6TJLYNA.js +0 -535
- package/dist/chunk-I6TJLYNA.js.map +0 -1
- package/dist/chunk-J7DHGLW6.mjs.map +0 -1
- package/dist/chunk-JOBLG62A.mjs +0 -476
- package/dist/chunk-JOBLG62A.mjs.map +0 -1
- package/dist/chunk-MAXA3HEP.mjs.map +0 -1
- package/dist/chunk-P5LXUDP6.mjs.map +0 -1
- package/dist/chunk-WDXEP4AJ.js.map +0 -1
package/README.md
CHANGED
|
@@ -54,13 +54,11 @@ export function Providers({ children }: { children: React.ReactNode }) {
|
|
|
54
54
|
{
|
|
55
55
|
id: 'solana:mainnet' as const,
|
|
56
56
|
label: 'Mainnet (Custom RPC)',
|
|
57
|
-
name: 'mainnet-beta' as const,
|
|
58
57
|
url: customRpcUrl,
|
|
59
58
|
},
|
|
60
59
|
{
|
|
61
60
|
id: 'solana:devnet' as const,
|
|
62
61
|
label: 'Devnet',
|
|
63
|
-
name: 'devnet' as const,
|
|
64
62
|
url: 'https://api.devnet.solana.com',
|
|
65
63
|
},
|
|
66
64
|
]
|
|
@@ -97,22 +95,38 @@ export function Providers({ children }: { children: React.ReactNode }) {
|
|
|
97
95
|
```typescript
|
|
98
96
|
'use client';
|
|
99
97
|
|
|
100
|
-
import { useConnector
|
|
98
|
+
import { useConnector } from '@solana/connector/react';
|
|
101
99
|
|
|
102
100
|
export function ConnectButton() {
|
|
103
|
-
const {
|
|
104
|
-
|
|
101
|
+
const {
|
|
102
|
+
connectors,
|
|
103
|
+
connectWallet,
|
|
104
|
+
disconnectWallet,
|
|
105
|
+
isConnected,
|
|
106
|
+
isConnecting,
|
|
107
|
+
isError,
|
|
108
|
+
walletError,
|
|
109
|
+
account,
|
|
110
|
+
} = useConnector();
|
|
105
111
|
|
|
106
|
-
if (
|
|
107
|
-
return
|
|
112
|
+
if (isError) {
|
|
113
|
+
return (
|
|
114
|
+
<div>
|
|
115
|
+
<p>Error: {walletError?.message ?? 'Unknown error'}</p>
|
|
116
|
+
</div>
|
|
117
|
+
);
|
|
108
118
|
}
|
|
109
119
|
|
|
110
|
-
if (!
|
|
120
|
+
if (!isConnected) {
|
|
111
121
|
return (
|
|
112
122
|
<div>
|
|
113
|
-
{
|
|
114
|
-
<button
|
|
115
|
-
|
|
123
|
+
{connectors.map(connector => (
|
|
124
|
+
<button
|
|
125
|
+
key={connector.id}
|
|
126
|
+
onClick={() => connectWallet(connector.id)}
|
|
127
|
+
disabled={isConnecting || !connector.ready}
|
|
128
|
+
>
|
|
129
|
+
{isConnecting ? 'Connecting...' : `Connect ${connector.name}`}
|
|
116
130
|
</button>
|
|
117
131
|
))}
|
|
118
132
|
</div>
|
|
@@ -121,8 +135,10 @@ export function ConnectButton() {
|
|
|
121
135
|
|
|
122
136
|
return (
|
|
123
137
|
<div>
|
|
124
|
-
<
|
|
125
|
-
<button onClick={
|
|
138
|
+
<span>{account}</span>
|
|
139
|
+
<button onClick={disconnectWallet}>
|
|
140
|
+
Disconnect
|
|
141
|
+
</button>
|
|
126
142
|
</div>
|
|
127
143
|
);
|
|
128
144
|
}
|
|
@@ -141,21 +157,37 @@ These are the main hooks you'll use in your components.
|
|
|
141
157
|
Main hook for wallet connection and state.
|
|
142
158
|
|
|
143
159
|
```typescript
|
|
144
|
-
import { useConnector } from '@solana/connector';
|
|
160
|
+
import { useConnector } from '@solana/connector/react';
|
|
145
161
|
|
|
146
162
|
function Component() {
|
|
147
163
|
const {
|
|
148
|
-
//
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
//
|
|
157
|
-
|
|
158
|
-
|
|
164
|
+
// vNext state (recommended)
|
|
165
|
+
connectors, // WalletConnectorMetadata[] - available wallet connectors
|
|
166
|
+
walletStatus, // WalletStatus - discriminated union state machine
|
|
167
|
+
connectorId, // WalletConnectorId | null - connected connector id
|
|
168
|
+
connector, // WalletConnectorMetadata | null - connected connector metadata
|
|
169
|
+
account, // Address | null - selected account address
|
|
170
|
+
sessionAccounts, // SessionAccount[] - all accounts in session
|
|
171
|
+
isConnected, // boolean - shorthand
|
|
172
|
+
isConnecting, // boolean - shorthand
|
|
173
|
+
isError, // boolean - shorthand
|
|
174
|
+
walletError, // Error | null - set when status is 'error'
|
|
175
|
+
|
|
176
|
+
// vNext actions (recommended)
|
|
177
|
+
connectWallet, // (connectorId, options?) => Promise<void>
|
|
178
|
+
disconnectWallet, // () => Promise<void>
|
|
179
|
+
|
|
180
|
+
// Legacy fields (deprecated; kept for backwards compatibility)
|
|
181
|
+
wallets,
|
|
182
|
+
selectedWallet,
|
|
183
|
+
selectedAccount,
|
|
184
|
+
accounts,
|
|
185
|
+
connected,
|
|
186
|
+
connecting,
|
|
187
|
+
|
|
188
|
+
// Legacy actions (deprecated; kept for backwards compatibility)
|
|
189
|
+
select,
|
|
190
|
+
disconnect,
|
|
159
191
|
} = useConnector();
|
|
160
192
|
}
|
|
161
193
|
```
|
|
@@ -165,32 +197,37 @@ function Component() {
|
|
|
165
197
|
```typescript
|
|
166
198
|
'use client';
|
|
167
199
|
|
|
168
|
-
import { useConnector } from '@solana/connector';
|
|
169
|
-
import { useState } from 'react';
|
|
200
|
+
import { useConnector } from '@solana/connector/react';
|
|
170
201
|
|
|
171
202
|
export function ConnectButton() {
|
|
172
|
-
const
|
|
173
|
-
const { connected, connecting, selectedWallet, selectedAccount, wallets, select } = useConnector();
|
|
203
|
+
const { connectors, connectWallet, disconnectWallet, isConnected, isConnecting, account } = useConnector();
|
|
174
204
|
|
|
175
|
-
if (
|
|
205
|
+
if (isConnecting) {
|
|
176
206
|
return <button disabled>Connecting...</button>;
|
|
177
207
|
}
|
|
178
208
|
|
|
179
|
-
if (
|
|
180
|
-
const shortAddress = `${
|
|
209
|
+
if (isConnected && account) {
|
|
210
|
+
const shortAddress = `${account.slice(0, 4)}...${account.slice(-4)}`;
|
|
181
211
|
return (
|
|
182
212
|
<div>
|
|
183
213
|
<span>{shortAddress}</span>
|
|
184
|
-
<button onClick={
|
|
214
|
+
<button onClick={disconnectWallet}>Disconnect</button>
|
|
185
215
|
</div>
|
|
186
216
|
);
|
|
187
217
|
}
|
|
188
218
|
|
|
189
219
|
return (
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
220
|
+
<div>
|
|
221
|
+
{connectors.map(connector => (
|
|
222
|
+
<button
|
|
223
|
+
key={connector.id}
|
|
224
|
+
onClick={() => connectWallet(connector.id)}
|
|
225
|
+
disabled={isConnecting || !connector.ready}
|
|
226
|
+
>
|
|
227
|
+
Connect {connector.name}
|
|
228
|
+
</button>
|
|
229
|
+
))}
|
|
230
|
+
</div>
|
|
194
231
|
);
|
|
195
232
|
}
|
|
196
233
|
```
|
|
@@ -308,6 +345,214 @@ function Component() {
|
|
|
308
345
|
|
|
309
346
|
---
|
|
310
347
|
|
|
348
|
+
## vNext API (Recommended)
|
|
349
|
+
|
|
350
|
+
The vNext API provides a cleaner, more type-safe approach to wallet connections using stable connector IDs and a wallet status state machine.
|
|
351
|
+
|
|
352
|
+
You can access the same vNext state + actions either through the focused hooks below, or via `useConnector()` (single hook) which also includes legacy compatibility fields.
|
|
353
|
+
|
|
354
|
+
### `useWallet()`
|
|
355
|
+
|
|
356
|
+
Primary hook for wallet status in vNext. Uses a discriminated union for type-safe status checks.
|
|
357
|
+
|
|
358
|
+
```typescript
|
|
359
|
+
import { useWallet } from '@solana/connector/react';
|
|
360
|
+
|
|
361
|
+
function Component() {
|
|
362
|
+
const {
|
|
363
|
+
status, // 'disconnected' | 'connecting' | 'connected' | 'error'
|
|
364
|
+
isConnected, // boolean shorthand
|
|
365
|
+
isConnecting,// boolean shorthand
|
|
366
|
+
account, // Address | null - Selected account address
|
|
367
|
+
accounts, // SessionAccount[] - All available accounts
|
|
368
|
+
connectorId, // WalletConnectorId | null - Connected wallet ID
|
|
369
|
+
error, // Error | null - Error if status is 'error'
|
|
370
|
+
} = useWallet();
|
|
371
|
+
|
|
372
|
+
if (status === 'connected') {
|
|
373
|
+
// TypeScript knows account is non-null here
|
|
374
|
+
return <p>Connected: {account}</p>;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
### `useWalletConnectors()`
|
|
380
|
+
|
|
381
|
+
Get available wallet connectors with stable IDs.
|
|
382
|
+
|
|
383
|
+
```typescript
|
|
384
|
+
import { useWalletConnectors } from '@solana/connector/react';
|
|
385
|
+
|
|
386
|
+
function WalletList() {
|
|
387
|
+
const connectors = useWalletConnectors();
|
|
388
|
+
|
|
389
|
+
return (
|
|
390
|
+
<ul>
|
|
391
|
+
{connectors.map(connector => (
|
|
392
|
+
<li key={connector.id}>
|
|
393
|
+
<img src={connector.icon} alt={connector.name} />
|
|
394
|
+
{connector.name}
|
|
395
|
+
{connector.ready ? '✓' : 'Not Ready'}
|
|
396
|
+
</li>
|
|
397
|
+
))}
|
|
398
|
+
</ul>
|
|
399
|
+
);
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### `useConnectWallet()`
|
|
404
|
+
|
|
405
|
+
Connect to a wallet using its stable connector ID.
|
|
406
|
+
|
|
407
|
+
```typescript
|
|
408
|
+
import { useConnectWallet, useWalletConnectors } from '@solana/connector/react';
|
|
409
|
+
|
|
410
|
+
function ConnectButton() {
|
|
411
|
+
const { connect, isConnecting, error, resetError } = useConnectWallet();
|
|
412
|
+
const connectors = useWalletConnectors();
|
|
413
|
+
|
|
414
|
+
return (
|
|
415
|
+
<div>
|
|
416
|
+
{connectors.map(connector => (
|
|
417
|
+
<button
|
|
418
|
+
key={connector.id}
|
|
419
|
+
onClick={() => connect(connector.id)}
|
|
420
|
+
disabled={isConnecting || !connector.ready}
|
|
421
|
+
>
|
|
422
|
+
Connect {connector.name}
|
|
423
|
+
</button>
|
|
424
|
+
))}
|
|
425
|
+
{error && (
|
|
426
|
+
<p>
|
|
427
|
+
Error: {error.message}
|
|
428
|
+
<button onClick={resetError}>Dismiss</button>
|
|
429
|
+
</p>
|
|
430
|
+
)}
|
|
431
|
+
</div>
|
|
432
|
+
);
|
|
433
|
+
}
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
### `useDisconnectWallet()`
|
|
437
|
+
|
|
438
|
+
Disconnect the current wallet session.
|
|
439
|
+
|
|
440
|
+
```typescript
|
|
441
|
+
import { useDisconnectWallet, useWallet } from '@solana/connector/react';
|
|
442
|
+
|
|
443
|
+
function DisconnectButton() {
|
|
444
|
+
const { isConnected } = useWallet();
|
|
445
|
+
const { disconnect, isDisconnecting } = useDisconnectWallet();
|
|
446
|
+
|
|
447
|
+
if (!isConnected) return null;
|
|
448
|
+
|
|
449
|
+
return (
|
|
450
|
+
<button onClick={disconnect} disabled={isDisconnecting}>
|
|
451
|
+
{isDisconnecting ? 'Disconnecting...' : 'Disconnect'}
|
|
452
|
+
</button>
|
|
453
|
+
);
|
|
454
|
+
}
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
### Silent-First Auto-Connect
|
|
458
|
+
|
|
459
|
+
The vNext API supports silent-first auto-connect, which attempts to reconnect without prompting the user:
|
|
460
|
+
|
|
461
|
+
```typescript
|
|
462
|
+
const { connect } = useConnectWallet();
|
|
463
|
+
|
|
464
|
+
// Silent connect (won't prompt user)
|
|
465
|
+
await connect('wallet-standard:phantom', {
|
|
466
|
+
silent: true,
|
|
467
|
+
allowInteractiveFallback: false,
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
// Silent-first with interactive fallback (prompts if silent fails)
|
|
471
|
+
await connect('wallet-standard:phantom', {
|
|
472
|
+
silent: true,
|
|
473
|
+
allowInteractiveFallback: true,
|
|
474
|
+
});
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
---
|
|
478
|
+
|
|
479
|
+
## Migration Guide (Legacy → vNext)
|
|
480
|
+
|
|
481
|
+
### Connect by Wallet Name → Connect by Connector ID
|
|
482
|
+
|
|
483
|
+
**Before (Legacy):**
|
|
484
|
+
|
|
485
|
+
```typescript
|
|
486
|
+
const { select, wallets } = useConnector();
|
|
487
|
+
await select('Phantom');
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
**After (vNext):**
|
|
491
|
+
|
|
492
|
+
```typescript
|
|
493
|
+
const { connect } = useConnectWallet();
|
|
494
|
+
await connect('wallet-standard:phantom');
|
|
495
|
+
// Or use connectors from useWalletConnectors()
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
### Check Connection Status
|
|
499
|
+
|
|
500
|
+
**Before (Legacy):**
|
|
501
|
+
|
|
502
|
+
```typescript
|
|
503
|
+
const { connected, connecting } = useConnector();
|
|
504
|
+
if (connected) {
|
|
505
|
+
/* ... */
|
|
506
|
+
}
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
**After (vNext):**
|
|
510
|
+
|
|
511
|
+
```typescript
|
|
512
|
+
const { status, isConnected, isConnecting } = useWallet();
|
|
513
|
+
if (status === 'connected') {
|
|
514
|
+
/* ... */
|
|
515
|
+
}
|
|
516
|
+
// Or use the boolean shorthand:
|
|
517
|
+
if (isConnected) {
|
|
518
|
+
/* ... */
|
|
519
|
+
}
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
### Get Selected Account
|
|
523
|
+
|
|
524
|
+
**Before (Legacy):**
|
|
525
|
+
|
|
526
|
+
```typescript
|
|
527
|
+
const { selectedAccount } = useConnector();
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
**After (vNext):**
|
|
531
|
+
|
|
532
|
+
```typescript
|
|
533
|
+
const { account } = useWallet();
|
|
534
|
+
// Or for full account info:
|
|
535
|
+
const { accounts, account } = useWallet();
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
### Disconnect
|
|
539
|
+
|
|
540
|
+
**Before (Legacy):**
|
|
541
|
+
|
|
542
|
+
```typescript
|
|
543
|
+
const { disconnect } = useConnector();
|
|
544
|
+
await disconnect();
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
**After (vNext):**
|
|
548
|
+
|
|
549
|
+
```typescript
|
|
550
|
+
const { disconnect } = useDisconnectWallet();
|
|
551
|
+
await disconnect();
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
---
|
|
555
|
+
|
|
311
556
|
## Transaction Signing
|
|
312
557
|
|
|
313
558
|
ConnectorKit provides powerful transaction signing capabilities with support for both legacy `@solana/web3.js` and modern `@solana/kit` APIs.
|
|
@@ -578,13 +823,11 @@ const config = getDefaultConfig({
|
|
|
578
823
|
{
|
|
579
824
|
id: 'solana:mainnet' as const,
|
|
580
825
|
label: 'Mainnet (Custom RPC)',
|
|
581
|
-
name: 'mainnet-beta' as const,
|
|
582
826
|
url: 'https://my-custom-rpc.com',
|
|
583
827
|
},
|
|
584
828
|
{
|
|
585
829
|
id: 'solana:devnet' as const,
|
|
586
830
|
label: 'Devnet',
|
|
587
|
-
name: 'devnet' as const,
|
|
588
831
|
url: 'https://api.devnet.solana.com',
|
|
589
832
|
},
|
|
590
833
|
],
|
|
@@ -606,6 +849,96 @@ const mobile = getDefaultMobileConfig({
|
|
|
606
849
|
</AppProvider>
|
|
607
850
|
```
|
|
608
851
|
|
|
852
|
+
### WalletConnect Integration
|
|
853
|
+
|
|
854
|
+
Connect mobile wallets via QR code or deep link using WalletConnect. This enables users to connect wallets like Trust Wallet, Exodus, and other WalletConnect-compatible Solana wallets.
|
|
855
|
+
|
|
856
|
+
**1. Install WalletConnect dependency:**
|
|
857
|
+
|
|
858
|
+
```bash
|
|
859
|
+
npm install @walletconnect/universal-provider
|
|
860
|
+
```
|
|
861
|
+
|
|
862
|
+
**2. Get a WalletConnect Cloud Project ID:**
|
|
863
|
+
|
|
864
|
+
Visit [cloud.walletconnect.com](https://cloud.walletconnect.com/) and create a project to get your `projectId`.
|
|
865
|
+
|
|
866
|
+
**3. Enable WalletConnect in your config:**
|
|
867
|
+
|
|
868
|
+
```typescript
|
|
869
|
+
'use client';
|
|
870
|
+
|
|
871
|
+
import { getDefaultConfig } from '@solana/connector/headless';
|
|
872
|
+
import { useMemo } from 'react';
|
|
873
|
+
import { AppProvider } from '@solana/connector/react';
|
|
874
|
+
|
|
875
|
+
export function Providers({ children }: { children: React.ReactNode }) {
|
|
876
|
+
const connectorConfig = useMemo(() => {
|
|
877
|
+
return getDefaultConfig({
|
|
878
|
+
appName: 'My App',
|
|
879
|
+
appUrl: 'https://myapp.com',
|
|
880
|
+
// Reads NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID from env
|
|
881
|
+
walletConnect: true,
|
|
882
|
+
});
|
|
883
|
+
}, []);
|
|
884
|
+
|
|
885
|
+
return (
|
|
886
|
+
<AppProvider connectorConfig={connectorConfig}>
|
|
887
|
+
{children}
|
|
888
|
+
<WalletConnectQRModal />
|
|
889
|
+
</AppProvider>
|
|
890
|
+
);
|
|
891
|
+
}
|
|
892
|
+
```
|
|
893
|
+
|
|
894
|
+
**4. Render a QR code when a pairing URI is available:**
|
|
895
|
+
|
|
896
|
+
```typescript
|
|
897
|
+
'use client';
|
|
898
|
+
|
|
899
|
+
import { useConnector } from '@solana/connector/react';
|
|
900
|
+
import { QRCodeSVG } from 'qrcode.react'; // npm install qrcode.react
|
|
901
|
+
|
|
902
|
+
export function WalletConnectQRModal() {
|
|
903
|
+
const { walletConnectUri, clearWalletConnectUri } = useConnector();
|
|
904
|
+
|
|
905
|
+
if (!walletConnectUri) return null;
|
|
906
|
+
|
|
907
|
+
return (
|
|
908
|
+
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50">
|
|
909
|
+
<div className="w-full max-w-sm rounded-xl bg-white p-6">
|
|
910
|
+
<h2 className="text-lg font-semibold">Scan with your wallet</h2>
|
|
911
|
+
<div className="mt-4 flex justify-center">
|
|
912
|
+
<QRCodeSVG value={walletConnectUri} size={256} />
|
|
913
|
+
</div>
|
|
914
|
+
<p className="mt-4 text-center text-sm text-gray-500">
|
|
915
|
+
Open your WalletConnect-compatible wallet and scan this QR code
|
|
916
|
+
</p>
|
|
917
|
+
<button
|
|
918
|
+
type="button"
|
|
919
|
+
onClick={clearWalletConnectUri}
|
|
920
|
+
className="mt-4 w-full rounded bg-gray-100 py-2"
|
|
921
|
+
>
|
|
922
|
+
Cancel
|
|
923
|
+
</button>
|
|
924
|
+
</div>
|
|
925
|
+
</div>
|
|
926
|
+
);
|
|
927
|
+
}
|
|
928
|
+
```
|
|
929
|
+
|
|
930
|
+
Once enabled, "WalletConnect" appears as a connector (id: `walletconnect`) in your wallet list. When selected, `useConnector().walletConnectUri` will be set to a `wc:` URI that you can display as a QR code or use for deep linking.
|
|
931
|
+
|
|
932
|
+
**Supported WalletConnect Solana methods:**
|
|
933
|
+
|
|
934
|
+
- `solana_getAccounts` / `solana_requestAccounts` - Get connected accounts
|
|
935
|
+
- `solana_signMessage` - Sign arbitrary messages
|
|
936
|
+
- `solana_signTransaction` - Sign transactions
|
|
937
|
+
- `solana_signAllTransactions` - Sign multiple transactions
|
|
938
|
+
- `solana_signAndSendTransaction` - Sign and broadcast transactions
|
|
939
|
+
|
|
940
|
+
See the [WalletConnect Solana documentation](https://docs.walletconnect.network/wallet-sdk/chain-support/solana) for more details.
|
|
941
|
+
|
|
609
942
|
---
|
|
610
943
|
|
|
611
944
|
## Security Considerations
|
|
@@ -662,7 +995,6 @@ const config = getDefaultConfig({
|
|
|
662
995
|
{
|
|
663
996
|
id: 'solana:mainnet' as const,
|
|
664
997
|
label: 'Mainnet',
|
|
665
|
-
name: 'mainnet-beta' as const,
|
|
666
998
|
url: `${getOrigin()}/api/rpc`, // Proxy URL
|
|
667
999
|
},
|
|
668
1000
|
// ... other clusters
|
|
@@ -995,27 +1327,28 @@ if (!result.success) {
|
|
|
995
1327
|
Use `ConnectorClient` for non-React frameworks:
|
|
996
1328
|
|
|
997
1329
|
```typescript
|
|
998
|
-
import { ConnectorClient, getDefaultConfig } from '@solana/connector/headless';
|
|
1330
|
+
import { ConnectorClient, getDefaultConfig, createConnectorId } from '@solana/connector/headless';
|
|
999
1331
|
|
|
1000
1332
|
// Create client
|
|
1001
1333
|
const client = new ConnectorClient(getDefaultConfig({ appName: 'My App' }));
|
|
1002
1334
|
|
|
1003
1335
|
// Get state
|
|
1004
1336
|
const state = client.getSnapshot();
|
|
1005
|
-
console.log('
|
|
1337
|
+
console.log('Connectors:', state.connectors);
|
|
1006
1338
|
|
|
1007
|
-
// Connect
|
|
1008
|
-
await client.
|
|
1339
|
+
// Connect (vNext)
|
|
1340
|
+
await client.connectWallet(createConnectorId('Phantom'));
|
|
1009
1341
|
|
|
1010
1342
|
// Subscribe to changes
|
|
1011
1343
|
const unsubscribe = client.subscribe(state => {
|
|
1012
1344
|
console.log('State updated:', state);
|
|
1013
1345
|
});
|
|
1014
1346
|
|
|
1015
|
-
// Disconnect
|
|
1016
|
-
await client.
|
|
1347
|
+
// Disconnect (vNext)
|
|
1348
|
+
await client.disconnectWallet();
|
|
1017
1349
|
|
|
1018
1350
|
// Cleanup
|
|
1351
|
+
unsubscribe();
|
|
1019
1352
|
client.destroy();
|
|
1020
1353
|
```
|
|
1021
1354
|
|
|
@@ -1063,7 +1396,7 @@ const config = getDefaultConfig({
|
|
|
1063
1396
|
|
|
1064
1397
|
```typescript
|
|
1065
1398
|
// Full library - includes React and headless
|
|
1066
|
-
import {
|
|
1399
|
+
import { AppProvider, useConnector, getDefaultConfig } from '@solana/connector';
|
|
1067
1400
|
```
|
|
1068
1401
|
|
|
1069
1402
|
### Headless Export (Framework Agnostic)
|
|
@@ -1077,7 +1410,7 @@ import { ConnectorClient, getDefaultConfig } from '@solana/connector/headless';
|
|
|
1077
1410
|
|
|
1078
1411
|
```typescript
|
|
1079
1412
|
// React-specific exports only
|
|
1080
|
-
import { useConnector,
|
|
1413
|
+
import { AppProvider, useConnector, useWallet, useConnectWallet } from '@solana/connector/react';
|
|
1081
1414
|
```
|
|
1082
1415
|
|
|
1083
1416
|
---
|
|
@@ -1086,9 +1419,20 @@ import { useConnector, useAccount } from '@solana/connector/react';
|
|
|
1086
1419
|
|
|
1087
1420
|
### Hooks
|
|
1088
1421
|
|
|
1422
|
+
#### vNext Hooks (Recommended)
|
|
1423
|
+
|
|
1424
|
+
| Hook | Description | Returns |
|
|
1425
|
+
| ----------------------- | --------------------------- | ----------------------------------------------------------------- |
|
|
1426
|
+
| `useWallet()` | Wallet status state machine | `{ status, isConnected, isConnecting, account, accounts, error }` |
|
|
1427
|
+
| `useWalletConnectors()` | Available wallet connectors | `WalletConnectorMetadata[]` |
|
|
1428
|
+
| `useConnectWallet()` | Connect by connector ID | `{ connect, isConnecting, error, resetError }` |
|
|
1429
|
+
| `useDisconnectWallet()` | Disconnect current wallet | `{ disconnect, isDisconnecting }` |
|
|
1430
|
+
|
|
1431
|
+
#### Legacy Hooks
|
|
1432
|
+
|
|
1089
1433
|
| Hook | Description | Returns |
|
|
1090
1434
|
| --------------------------- | --------------------------------------- | ---------------------------------------------------------------------------------- |
|
|
1091
|
-
| `useConnector()` | Main wallet connection hook
|
|
1435
|
+
| `useConnector()` | Main wallet connection hook (vNext + legacy) | `ConnectorSnapshot` |
|
|
1092
1436
|
| `useAccount()` | Account management hook | `{ address, formatted, copy, copied, accounts, selectAccount }` |
|
|
1093
1437
|
| `useCluster()` | Network/cluster management hook | `{ cluster, clusters, setCluster, isMainnet, isDevnet, rpcUrl }` |
|
|
1094
1438
|
| `useWalletInfo()` | Wallet metadata hook | `{ name, icon, wallet, connecting }` |
|
|
@@ -1124,7 +1468,7 @@ import type {
|
|
|
1124
1468
|
// Configuration
|
|
1125
1469
|
ConnectorConfig,
|
|
1126
1470
|
DefaultConfigOptions,
|
|
1127
|
-
|
|
1471
|
+
ExtendedConnectorConfig,
|
|
1128
1472
|
|
|
1129
1473
|
// State & Info
|
|
1130
1474
|
ConnectorState,
|
|
@@ -1140,6 +1484,14 @@ import type {
|
|
|
1140
1484
|
SolanaCluster,
|
|
1141
1485
|
SolanaClusterId,
|
|
1142
1486
|
|
|
1487
|
+
// vNext Session Types
|
|
1488
|
+
WalletConnectorId,
|
|
1489
|
+
WalletConnectorMetadata,
|
|
1490
|
+
WalletSession,
|
|
1491
|
+
WalletStatus,
|
|
1492
|
+
SessionAccount,
|
|
1493
|
+
ConnectOptions,
|
|
1494
|
+
|
|
1143
1495
|
// Hook Returns
|
|
1144
1496
|
UseClusterReturn,
|
|
1145
1497
|
UseAccountReturn,
|
|
@@ -1208,6 +1560,7 @@ Compatible with all [Wallet Standard](https://github.com/wallet-standard/wallet-
|
|
|
1208
1560
|
- **Glow** - Browser extension
|
|
1209
1561
|
- **Brave Wallet** - Built-in browser wallet
|
|
1210
1562
|
- **Solana Mobile** - All mobile wallet adapter compatible wallets
|
|
1563
|
+
- **WalletConnect** - Connect any WalletConnect-compatible mobile wallet via QR code
|
|
1211
1564
|
- **Any Wallet Standard wallet** - Full compatibility
|
|
1212
1565
|
|
|
1213
1566
|
---
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/lib/core/try-catch.ts
|
|
4
|
+
async function tryCatch(promise) {
|
|
5
|
+
try {
|
|
6
|
+
return { data: await promise, error: null };
|
|
7
|
+
} catch (error) {
|
|
8
|
+
return { data: null, error };
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
function tryCatchSync(fn) {
|
|
12
|
+
try {
|
|
13
|
+
return { data: fn(), error: null };
|
|
14
|
+
} catch (error) {
|
|
15
|
+
return { data: null, error };
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function isSuccess(result) {
|
|
19
|
+
return result.error === null;
|
|
20
|
+
}
|
|
21
|
+
function isFailure(result) {
|
|
22
|
+
return result.error !== null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// src/utils/transaction-format.ts
|
|
26
|
+
function isWeb3jsTransaction(tx) {
|
|
27
|
+
return tx !== null && typeof tx == "object" && "serialize" in tx && typeof tx.serialize == "function";
|
|
28
|
+
}
|
|
29
|
+
function serializeTransaction(tx) {
|
|
30
|
+
if (isWeb3jsTransaction(tx))
|
|
31
|
+
return tx.serialize({
|
|
32
|
+
requireAllSignatures: false,
|
|
33
|
+
verifySignatures: false
|
|
34
|
+
});
|
|
35
|
+
if (tx instanceof Uint8Array)
|
|
36
|
+
return tx;
|
|
37
|
+
if (ArrayBuffer.isView(tx))
|
|
38
|
+
return new Uint8Array(tx.buffer, tx.byteOffset, tx.byteLength);
|
|
39
|
+
throw new Error("Unsupported transaction format - must be Transaction, VersionedTransaction, or Uint8Array");
|
|
40
|
+
}
|
|
41
|
+
function isLegacyTransaction(bytes) {
|
|
42
|
+
return bytes.length === 0 ? false : (bytes[0] & 128) === 0;
|
|
43
|
+
}
|
|
44
|
+
async function deserializeToWeb3jsTransaction(bytes) {
|
|
45
|
+
if (isLegacyTransaction(bytes)) {
|
|
46
|
+
let { Transaction } = await import('@solana/web3.js');
|
|
47
|
+
return Transaction.from(bytes);
|
|
48
|
+
} else {
|
|
49
|
+
let { VersionedTransaction } = await import('@solana/web3.js');
|
|
50
|
+
return VersionedTransaction.deserialize(bytes);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function prepareTransactionForWallet(tx) {
|
|
54
|
+
let wasWeb3js = isWeb3jsTransaction(tx);
|
|
55
|
+
return { serialized: serializeTransaction(tx), wasWeb3js };
|
|
56
|
+
}
|
|
57
|
+
async function convertSignedTransaction(signedBytes, wasWeb3js) {
|
|
58
|
+
return wasWeb3js ? await deserializeToWeb3jsTransaction(signedBytes) : signedBytes;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
exports.convertSignedTransaction = convertSignedTransaction;
|
|
62
|
+
exports.isFailure = isFailure;
|
|
63
|
+
exports.isSuccess = isSuccess;
|
|
64
|
+
exports.isWeb3jsTransaction = isWeb3jsTransaction;
|
|
65
|
+
exports.prepareTransactionForWallet = prepareTransactionForWallet;
|
|
66
|
+
exports.tryCatch = tryCatch;
|
|
67
|
+
exports.tryCatchSync = tryCatchSync;
|
|
68
|
+
//# sourceMappingURL=chunk-4KD6HQQG.js.map
|
|
69
|
+
//# sourceMappingURL=chunk-4KD6HQQG.js.map
|