@phantom/react-sdk 0.3.9 → 1.0.0-beta.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # @phantom/react-sdk
2
2
 
3
- React hooks for integrating Phantom wallet functionality into React applications with native transaction support.
3
+ React hooks for integrating Phantom wallet functionality into React applications with chain-specific operations.
4
4
 
5
5
  ## Installation
6
6
 
@@ -16,8 +16,6 @@ Install additional dependencies based on the networks you want to support:
16
16
  | --------------- | ---------------------------------- |
17
17
  | Solana | `@solana/web3.js` OR `@solana/kit` |
18
18
  | Ethereum/EVM | `viem` |
19
- | Bitcoin | `bitcoinjs-lib` |
20
- | Sui | `@mysten/sui.js` |
21
19
 
22
20
  **Example for Solana + Ethereum support (using @solana/web3.js):**
23
21
 
@@ -31,34 +29,65 @@ npm install @phantom/react-sdk @solana/web3.js viem
31
29
  npm install @phantom/react-sdk @solana/kit viem
32
30
  ```
33
31
 
34
- For complete dependency information and bundle optimization tips, see the [@phantom/browser-sdk documentation](../browser-sdk/README.md#bundle-optimization-tips).
35
-
36
32
  ## Quick Start
37
33
 
38
- ### Basic Setup
34
+ ### Basic Setup with Chain-Specific Operations
39
35
 
40
36
  ```tsx
41
- import { PhantomProvider } from "@phantom/react-sdk";
42
- import { AddressType } from "@phantom/client";
37
+ import { PhantomProvider, useConnect, useSolana, useEthereum } from "@phantom/react-sdk";
38
+ import { AddressType } from "@phantom/browser-sdk";
43
39
 
44
40
  function App() {
45
41
  return (
46
42
  <PhantomProvider
47
43
  config={{
48
44
  providerType: "injected", // Uses Phantom browser extension
45
+ addressTypes: [AddressType.solana, AddressType.ethereum],
49
46
  }}
50
47
  >
51
- <YourApp />
48
+ <WalletComponent />
52
49
  </PhantomProvider>
53
50
  );
54
51
  }
52
+
53
+ function WalletComponent() {
54
+ const { connect, isConnecting } = useConnect();
55
+ const solana = useSolana();
56
+ const ethereum = useEthereum();
57
+
58
+ const handleConnect = async () => {
59
+ const { addresses } = await connect();
60
+ console.log("Connected addresses:", addresses);
61
+ };
62
+
63
+ const signSolanaMessage = async () => {
64
+ const signature = await solana.signMessage("Hello Solana!");
65
+ console.log("Solana signature:", signature);
66
+ };
67
+
68
+ const signEthereumMessage = async () => {
69
+ const accounts = await ethereum.getAccounts();
70
+ const signature = await ethereum.signPersonalMessage("Hello Ethereum!", accounts[0]);
71
+ console.log("Ethereum signature:", signature);
72
+ };
73
+
74
+ return (
75
+ <div>
76
+ <button onClick={handleConnect} disabled={isConnecting}>
77
+ {isConnecting ? "Connecting..." : "Connect Wallet"}
78
+ </button>
79
+ <button onClick={signSolanaMessage}>Sign Solana Message</button>
80
+ <button onClick={signEthereumMessage}>Sign Ethereum Message</button>
81
+ </div>
82
+ );
83
+ }
55
84
  ```
56
85
 
57
86
  ### Embedded Wallet Setup
58
87
 
59
88
  ```tsx
60
89
  import { PhantomProvider } from "@phantom/react-sdk";
61
- import { AddressType } from "@phantom/client";
90
+ import { AddressType } from "@phantom/browser-sdk";
62
91
 
63
92
  function App() {
64
93
  return (
@@ -77,6 +106,61 @@ function App() {
77
106
  }
78
107
  ```
79
108
 
109
+ ## Connection Flow
110
+
111
+ The React SDK follows a clear connection pattern:
112
+
113
+ 1. **Provider Setup**: Wrap your app with `PhantomProvider`
114
+ 2. **Connection**: Use `useConnect()` to establish wallet connection
115
+ 3. **Chain Operations**: Use chain-specific hooks (`useSolana()`, `useEthereum()`) for transactions and signing
116
+
117
+ ```tsx
118
+ function WalletExample() {
119
+ const { connect } = useConnect();
120
+ const solana = useSolana();
121
+ const ethereum = useEthereum();
122
+
123
+ // 1. Connect first
124
+ const handleConnect = async () => {
125
+ await connect();
126
+ };
127
+
128
+ // 2. Then use chain-specific operations
129
+ const sendSolanaTransaction = async () => {
130
+ const result = await solana.signAndSendTransaction(transaction);
131
+ };
132
+
133
+ const sendEthereumTransaction = async () => {
134
+ const result = await ethereum.sendTransaction(transaction);
135
+ };
136
+ }
137
+ ```
138
+
139
+ ### Connection Options
140
+
141
+ For embedded user-wallets, you can specify authentication providers:
142
+
143
+ ```tsx
144
+ const { connect } = useConnect();
145
+
146
+ // Default: Show provider selection screen
147
+ await connect();
148
+
149
+ // Google authentication (skips provider selection)
150
+ await connect({
151
+ authOptions: {
152
+ provider: "google",
153
+ },
154
+ });
155
+
156
+ // Apple authentication (skips provider selection)
157
+ await connect({
158
+ authOptions: {
159
+ provider: "apple",
160
+ },
161
+ });
162
+ ```
163
+
80
164
  ## Provider Types
81
165
 
82
166
  ### Injected Provider
@@ -87,6 +171,7 @@ Uses the Phantom browser extension installed by the user.
87
171
  <PhantomProvider
88
172
  config={{
89
173
  providerType: "injected",
174
+ addressTypes: [AddressType.solana, AddressType.ethereum],
90
175
  }}
91
176
  >
92
177
  <YourApp />
@@ -167,7 +252,9 @@ When using `AddressType.solana`, you can choose between two Solana libraries:
167
252
 
168
253
  ## Available Hooks
169
254
 
170
- ### useConnect
255
+ ### Core Connection Hooks
256
+
257
+ #### useConnect
171
258
 
172
259
  Connect to wallet:
173
260
 
@@ -175,7 +262,7 @@ Connect to wallet:
175
262
  import { useConnect } from "@phantom/react-sdk";
176
263
 
177
264
  function ConnectButton() {
178
- const { connect, isLoading, error } = useConnect();
265
+ const { connect, isConnecting, error } = useConnect();
179
266
 
180
267
  const handleConnect = async () => {
181
268
  try {
@@ -187,14 +274,14 @@ function ConnectButton() {
187
274
  };
188
275
 
189
276
  return (
190
- <button onClick={handleConnect} disabled={isLoading}>
191
- {isLoading ? "Connecting..." : "Connect Wallet"}
277
+ <button onClick={handleConnect} disabled={isConnecting}>
278
+ {isConnecting ? "Connecting..." : "Connect Wallet"}
192
279
  </button>
193
280
  );
194
281
  }
195
282
  ```
196
283
 
197
- ### useAccounts
284
+ #### useAccounts
198
285
 
199
286
  Get connected wallet addresses:
200
287
 
@@ -220,7 +307,25 @@ function WalletAddresses() {
220
307
  }
221
308
  ```
222
309
 
223
- ### useIsExtensionInstalled
310
+ #### useDisconnect
311
+
312
+ Disconnect from wallet:
313
+
314
+ ```tsx
315
+ import { useDisconnect } from "@phantom/react-sdk";
316
+
317
+ function DisconnectButton() {
318
+ const { disconnect, isDisconnecting } = useDisconnect();
319
+
320
+ return (
321
+ <button onClick={disconnect} disabled={isDisconnecting}>
322
+ {isDisconnecting ? "Disconnecting..." : "Disconnect"}
323
+ </button>
324
+ );
325
+ }
326
+ ```
327
+
328
+ #### useIsExtensionInstalled
224
329
 
225
330
  Check if the Phantom browser extension is installed (for injected provider):
226
331
 
@@ -251,197 +356,299 @@ function ExtensionStatus() {
251
356
  }
252
357
  ```
253
358
 
254
- **Features:**
255
-
256
- - **Session-based caching**: Result is cached during the browser session to avoid redundant checks
257
- - **Automatic detection**: Runs automatically when the hook is first used
258
- - **Loading states**: Provides `isLoading` during the initial check
259
- - **Performance optimized**: Subsequent calls return cached result instantly
260
-
261
- **Use cases:**
359
+ ### Chain-Specific Hooks
262
360
 
263
- - Show installation prompts for users without the extension
264
- - Conditionally render UI based on extension availability
265
- - Provide fallback options when extension is not installed
361
+ #### useSolana
266
362
 
267
- ### useDisconnect
268
-
269
- Disconnect from wallet:
363
+ Hook for Solana chain operations:
270
364
 
271
365
  ```tsx
272
- import { useDisconnect } from "@phantom/react-sdk";
366
+ import { useSolana } from "@phantom/react-sdk";
367
+ import { VersionedTransaction, TransactionMessage, SystemProgram, PublicKey, Connection } from "@solana/web3.js";
273
368
 
274
- function DisconnectButton() {
275
- const { disconnect, isLoading } = useDisconnect();
369
+ function SolanaOperations() {
370
+ const solana = useSolana();
276
371
 
277
- return (
278
- <button onClick={disconnect} disabled={isLoading}>
279
- {isLoading ? "Disconnecting..." : "Disconnect"}
280
- </button>
281
- );
282
- }
283
- ```
372
+ const signMessage = async () => {
373
+ const signature = await solana.signMessage("Hello Solana!");
374
+ console.log("Signature:", signature);
375
+ };
284
376
 
285
- ### useSignMessage
377
+ const signAndSendTransaction = async () => {
378
+ // Create transaction
379
+ const connection = new Connection("https://api.mainnet-beta.solana.com");
380
+ const { blockhash } = await connection.getLatestBlockhash();
381
+
382
+ const fromAddress = await solana.getPublicKey();
383
+ const transferInstruction = SystemProgram.transfer({
384
+ fromPubkey: new PublicKey(fromAddress),
385
+ toPubkey: new PublicKey(toAddress),
386
+ lamports: 1000000, // 0.001 SOL
387
+ });
286
388
 
287
- Sign messages with native string input:
389
+ const messageV0 = new TransactionMessage({
390
+ payerKey: new PublicKey(fromAddress),
391
+ recentBlockhash: blockhash,
392
+ instructions: [transferInstruction],
393
+ }).compileToV0Message();
288
394
 
289
- ```tsx
290
- import { useSignMessage, NetworkId } from "@phantom/react-sdk";
395
+ const transaction = new VersionedTransaction(messageV0);
291
396
 
292
- function SignMessage() {
293
- const { signMessage, isLoading, error } = useSignMessage();
397
+ // Sign and send
398
+ const result = await solana.signAndSendTransaction(transaction);
399
+ console.log("Transaction sent:", result.hash);
400
+ };
294
401
 
295
- const handleSign = async () => {
296
- try {
297
- const signature = await signMessage({
298
- message: "Hello from Phantom!",
299
- networkId: NetworkId.SOLANA_MAINNET,
300
- });
301
- console.log("Signature:", signature);
302
- } catch (err) {
303
- console.error("Failed to sign:", err);
304
- }
402
+ const switchNetwork = async () => {
403
+ await solana.switchNetwork('devnet');
305
404
  };
306
405
 
307
406
  return (
308
- <button onClick={handleSign} disabled={isLoading}>
309
- {isLoading ? "Signing..." : "Sign Message"}
310
- </button>
407
+ <div>
408
+ <button onClick={signMessage}>Sign Message</button>
409
+ <button onClick={signAndSendTransaction}>Send Transaction</button>
410
+ <button onClick={switchNetwork}>Switch to Devnet</button>
411
+ <p>Connected: {solana.isConnected ? 'Yes' : 'No'}</p>
412
+ </div>
311
413
  );
312
414
  }
313
415
  ```
314
416
 
315
- ### useSignAndSendTransaction
417
+ **Available methods:**
418
+ - `signMessage(message)` - Sign a message
419
+ - `signTransaction(transaction)` - Sign without sending
420
+ - `signAndSendTransaction(transaction)` - Sign and send
421
+ - `switchNetwork(network)` - Switch between mainnet/devnet
422
+ - `getPublicKey()` - Get current public key
423
+ - `isConnected` - Connection status
424
+ - `isAvailable` - Provider availability
425
+
426
+ #### useEthereum
316
427
 
317
- #### Solana Transaction
428
+ Hook for Ethereum chain operations:
318
429
 
319
430
  ```tsx
320
- import { useSignAndSendTransaction, NetworkId } from "@phantom/react-sdk";
321
- import {
322
- VersionedTransaction,
323
- TransactionMessage,
324
- SystemProgram,
325
- PublicKey,
326
- LAMPORTS_PER_SOL,
327
- Connection,
328
- } from "@solana/web3.js";
329
-
330
- function SendSolanaTransaction() {
331
- const { signAndSendTransaction, isLoading, error } = useSignAndSendTransaction();
332
-
333
- const handleSend = async () => {
334
- // Get recent blockhash
335
- const connection = new Connection("https://api.mainnet-beta.solana.com");
336
- const { blockhash } = await connection.getLatestBlockhash();
431
+ import { useEthereum } from "@phantom/react-sdk";
337
432
 
338
- // Create transfer instruction
339
- const transferInstruction = SystemProgram.transfer({
340
- fromPubkey: new PublicKey(fromAddress),
341
- toPubkey: new PublicKey(toAddress),
342
- lamports: 0.001 * LAMPORTS_PER_SOL,
343
- });
433
+ function EthereumOperations() {
434
+ const ethereum = useEthereum();
344
435
 
345
- // Create VersionedTransaction
346
- const messageV0 = new TransactionMessage({
347
- payerKey: new PublicKey(fromAddress),
348
- recentBlockhash: blockhash,
349
- instructions: [transferInstruction],
350
- }).compileToV0Message();
436
+ const signPersonalMessage = async () => {
437
+ const accounts = await ethereum.getAccounts();
438
+ const signature = await ethereum.signPersonalMessage("Hello Ethereum!", accounts[0]);
439
+ console.log("Signature:", signature);
440
+ };
351
441
 
352
- const transaction = new VersionedTransaction(messageV0);
442
+ const signTypedData = async () => {
443
+ const accounts = await ethereum.getAccounts();
444
+ const typedData = {
445
+ types: {
446
+ EIP712Domain: [
447
+ { name: "name", type: "string" },
448
+ { name: "version", type: "string" },
449
+ { name: "chainId", type: "uint256" },
450
+ { name: "verifyingContract", type: "address" }
451
+ ],
452
+ Mail: [
453
+ { name: "from", type: "string" },
454
+ { name: "to", type: "string" },
455
+ { name: "contents", type: "string" }
456
+ ]
457
+ },
458
+ primaryType: "Mail",
459
+ domain: {
460
+ name: "Ether Mail",
461
+ version: "1",
462
+ chainId: 1,
463
+ verifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
464
+ },
465
+ message: {
466
+ from: "Alice",
467
+ to: "Bob",
468
+ contents: "Hello!"
469
+ }
470
+ };
471
+
472
+ const signature = await ethereum.signTypedData(typedData);
473
+ console.log("Typed data signature:", signature);
474
+ };
353
475
 
354
- try {
355
- const result = await signAndSendTransaction({
356
- networkId: NetworkId.SOLANA_MAINNET,
357
- transaction: transaction, // Native VersionedTransaction object!
358
- });
359
- console.log("Transaction sent:", result.rawTransaction);
360
- } catch (err) {
361
- console.error("Failed to send:", err);
362
- }
476
+ const sendTransaction = async () => {
477
+ const result = await ethereum.sendTransaction({
478
+ to: "0x742d35Cc6634C0532925a3b8D4C8db86fB5C4A7E",
479
+ value: "1000000000000000000", // 1 ETH in wei
480
+ gas: "21000",
481
+ });
482
+ console.log("Transaction sent:", result.hash);
483
+ };
484
+
485
+ const switchChain = async () => {
486
+ await ethereum.switchChain(137); // Switch to Polygon
363
487
  };
364
488
 
365
489
  return (
366
- <button onClick={handleSend} disabled={isLoading}>
367
- {isLoading ? "Sending..." : "Send SOL"}
368
- </button>
490
+ <div>
491
+ <button onClick={signPersonalMessage}>Sign Personal Message</button>
492
+ <button onClick={signTypedData}>Sign Typed Data</button>
493
+ <button onClick={sendTransaction}>Send Transaction</button>
494
+ <button onClick={switchChain}>Switch to Polygon</button>
495
+ <p>Connected: {ethereum.isConnected ? 'Yes' : 'No'}</p>
496
+ </div>
369
497
  );
370
498
  }
371
499
  ```
372
500
 
373
- #### Ethereum Transaction (with Viem)
501
+ **Available methods:**
502
+ - `request(args)` - EIP-1193 requests
503
+ - `signPersonalMessage(message, address)` - Sign personal message
504
+ - `signTypedData(typedData)` - Sign EIP-712 typed data
505
+ - `sendTransaction(transaction)` - Send transaction
506
+ - `switchChain(chainId)` - Switch chains
507
+ - `getChainId()` - Get current chain ID
508
+ - `getAccounts()` - Get connected accounts
509
+ - `isConnected` - Connection status
510
+ - `isAvailable` - Provider availability
374
511
 
375
- ```tsx
376
- import { useSignAndSendTransaction, NetworkId } from "@phantom/react-sdk";
377
- import { parseEther, parseGwei } from "viem";
512
+ ### Auto-Confirm Hook (Injected Provider Only)
378
513
 
379
- function SendEthereumTransaction() {
380
- const { signAndSendTransaction, isLoading } = useSignAndSendTransaction();
514
+ #### useAutoConfirm
381
515
 
382
- const handleSend = async () => {
516
+ Hook for managing auto-confirm functionality with the Phantom extension. Auto-confirm allows transactions to be automatically approved without user interaction for enabled chains.
517
+
518
+ > **Note**: This hook only works with the `injected` provider type (Phantom browser extension). It will throw errors for embedded providers.
519
+
520
+ ```tsx
521
+ import { useAutoConfirm, NetworkId } from "@phantom/react-sdk";
522
+
523
+ function AutoConfirmControls() {
524
+ const {
525
+ enable,
526
+ disable,
527
+ status,
528
+ supportedChains,
529
+ isLoading,
530
+ error,
531
+ refetch,
532
+ } = useAutoConfirm();
533
+
534
+ const handleEnable = async () => {
383
535
  try {
384
- const result = await signAndSendTransaction({
385
- networkId: NetworkId.ETHEREUM_MAINNET,
386
- transaction: {
387
- to: "0x742d35Cc6634C0532925a3b8D4C8db86fB5C4A7E",
388
- value: parseEther("0.001"), // 0.001 ETH
389
- gas: 21000n,
390
- gasPrice: parseGwei("20"), // 20 gwei
391
- },
536
+ // Enable auto-confirm for specific chains
537
+ const result = await enable({
538
+ chains: [NetworkId.SOLANA_DEVNET, NetworkId.ETHEREUM_MAINNET]
392
539
  });
393
- console.log("Transaction sent:", result);
540
+ console.log("Auto-confirm enabled:", result);
394
541
  } catch (err) {
395
- console.error("Failed to send:", err);
542
+ console.error("Failed to enable auto-confirm:", err);
396
543
  }
397
544
  };
398
545
 
546
+ const handleDisable = async () => {
547
+ try {
548
+ await disable();
549
+ console.log("Auto-confirm disabled");
550
+ } catch (err) {
551
+ console.error("Failed to disable auto-confirm:", err);
552
+ }
553
+ };
554
+
555
+ if (isLoading) {
556
+ return <div>Loading auto-confirm settings...</div>;
557
+ }
558
+
559
+ if (error) {
560
+ return <div>Error: {error.message}</div>;
561
+ }
562
+
399
563
  return (
400
- <button onClick={handleSend} disabled={isLoading}>
401
- {isLoading ? "Sending..." : "Send ETH"}
402
- </button>
564
+ <div>
565
+ <h3>Auto-Confirm Settings</h3>
566
+
567
+ <div>
568
+ <strong>Status:</strong> {status?.enabled ? "Enabled" : "Disabled"}
569
+ {status?.chains && (
570
+ <div>
571
+ <strong>Active Chains:</strong>
572
+ <ul>
573
+ {status.chains.map((chain) => (
574
+ <li key={chain}>{chain}</li>
575
+ ))}
576
+ </ul>
577
+ </div>
578
+ )}
579
+ </div>
580
+
581
+ <div>
582
+ <strong>Supported Chains:</strong>
583
+ {supportedChains?.chains && (
584
+ <ul>
585
+ {supportedChains.chains.map((chain) => (
586
+ <li key={chain}>{chain}</li>
587
+ ))}
588
+ </ul>
589
+ )}
590
+ </div>
591
+
592
+ <div>
593
+ <button onClick={handleEnable} disabled={isLoading}>
594
+ Enable Auto-Confirm
595
+ </button>
596
+ <button onClick={handleDisable} disabled={isLoading}>
597
+ Disable Auto-Confirm
598
+ </button>
599
+ <button onClick={refetch} disabled={isLoading}>
600
+ Refresh Status
601
+ </button>
602
+ </div>
603
+ </div>
403
604
  );
404
605
  }
405
606
  ```
406
607
 
407
- ## Network Support
408
-
409
- ### Supported Networks
608
+ **Hook Interface:**
410
609
 
411
- The SDK automatically determines the transaction type from the NetworkId:
412
-
413
- #### Solana
414
-
415
- - `NetworkId.SOLANA_MAINNET`
416
- - `NetworkId.SOLANA_DEVNET`
417
- - `NetworkId.SOLANA_TESTNET`
418
-
419
- #### Ethereum/EVM
610
+ ```typescript
611
+ interface UseAutoConfirmResult {
612
+ enable: (params: AutoConfirmEnableParams) => Promise<AutoConfirmResult>;
613
+ disable: () => Promise<void>;
614
+ status: AutoConfirmResult | null;
615
+ supportedChains: AutoConfirmSupportedChainsResult | null;
616
+ isLoading: boolean;
617
+ error: Error | null;
618
+ refetch: () => Promise<void>;
619
+ }
420
620
 
421
- - `NetworkId.ETHEREUM_MAINNET`
422
- - `NetworkId.ETHEREUM_SEPOLIA`
423
- - `NetworkId.POLYGON_MAINNET`
424
- - `NetworkId.ARBITRUM_ONE`
425
- - `NetworkId.OPTIMISM_MAINNET`
426
- - `NetworkId.BASE_MAINNET`
621
+ interface AutoConfirmEnableParams {
622
+ chains?: NetworkId[]; // Optional array of chains to enable
623
+ }
427
624
 
428
- #### Bitcoin
625
+ interface AutoConfirmResult {
626
+ enabled: boolean;
627
+ chains: NetworkId[];
628
+ }
429
629
 
430
- - `NetworkId.BITCOIN_MAINNET`
431
- - `NetworkId.BITCOIN_TESTNET`
630
+ interface AutoConfirmSupportedChainsResult {
631
+ chains: NetworkId[];
632
+ }
633
+ ```
432
634
 
433
- #### Sui
635
+ **Available Methods:**
434
636
 
435
- - `NetworkId.SUI_MAINNET`
436
- - `NetworkId.SUI_TESTNET`
437
- - `NetworkId.SUI_DEVNET`
637
+ - `enable(params)` - Enable auto-confirm for specific chains
638
+ - `disable()` - Disable auto-confirm completely
639
+ - `refetch()` - Refresh status and supported chains from extension
640
+ - `status` - Current auto-confirm status (enabled/disabled and active chains)
641
+ - `supportedChains` - List of chains that support auto-confirm
642
+ - `isLoading` - Loading state for operations
643
+ - `error` - Any errors from auto-confirm operations
438
644
 
439
- ### Provider Network Support
645
+ **Usage Notes:**
440
646
 
441
- | Provider Type | Network Support |
442
- | ------------- | ----------------------------------------------- |
443
- | **Injected** | All networks supported by Phantom extension |
444
- | **Embedded** | All networks based on configured `addressTypes` |
647
+ - Auto-confirm automatically fetches status and supported chains when the hook initializes
648
+ - Only works with injected provider (Phantom extension)
649
+ - Throws errors for embedded providers
650
+ - Status is automatically updated after enable/disable operations
651
+ - Use `refetch()` to manually refresh data from the extension
445
652
 
446
653
  ## Transaction Examples
447
654
 
@@ -449,10 +656,10 @@ The SDK automatically determines the transaction type from the NetworkId:
449
656
 
450
657
  ```tsx
451
658
  import { VersionedTransaction, TransactionMessage, SystemProgram, PublicKey, Connection } from "@solana/web3.js";
452
- import { useSignAndSendTransaction, NetworkId } from "@phantom/react-sdk";
659
+ import { useSolana } from "@phantom/react-sdk";
453
660
 
454
661
  function SolanaExample() {
455
- const { signAndSendTransaction } = useSignAndSendTransaction();
662
+ const solana = useSolana();
456
663
 
457
664
  const sendTransaction = async () => {
458
665
  // Get recent blockhash
@@ -460,6 +667,7 @@ function SolanaExample() {
460
667
  const { blockhash } = await connection.getLatestBlockhash();
461
668
 
462
669
  // Create transfer instruction
670
+ const fromAddress = await solana.getPublicKey();
463
671
  const transferInstruction = SystemProgram.transfer({
464
672
  fromPubkey: new PublicKey(fromAddress),
465
673
  toPubkey: new PublicKey(toAddress),
@@ -475,12 +683,12 @@ function SolanaExample() {
475
683
 
476
684
  const transaction = new VersionedTransaction(messageV0);
477
685
 
478
- // No serialization or encoding needed!
479
- const result = await signAndSendTransaction({
480
- networkId: NetworkId.SOLANA_MAINNET,
481
- transaction,
482
- });
686
+ // Sign and send using chain-specific hook
687
+ const result = await solana.signAndSendTransaction(transaction);
688
+ console.log("Transaction sent:", result.hash);
483
689
  };
690
+
691
+ return <button onClick={sendTransaction}>Send SOL</button>;
484
692
  }
485
693
  ```
486
694
 
@@ -496,15 +704,16 @@ import {
496
704
  address,
497
705
  compileTransaction,
498
706
  } from "@solana/kit";
499
- import { useSignAndSendTransaction, NetworkId } from "@phantom/react-sdk";
707
+ import { useSolana } from "@phantom/react-sdk";
500
708
 
501
709
  function SolanaKitExample() {
502
- const { signAndSendTransaction } = useSignAndSendTransaction();
710
+ const solana = useSolana();
503
711
 
504
712
  const sendTransaction = async () => {
505
713
  const rpc = createSolanaRpc("https://api.mainnet-beta.solana.com");
506
714
  const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
507
715
 
716
+ const userPublicKey = await solana.getPublicKey();
508
717
  const transactionMessage = pipe(
509
718
  createTransactionMessage({ version: 0 }),
510
719
  tx => setTransactionMessageFeePayer(address(userPublicKey), tx),
@@ -513,11 +722,12 @@ function SolanaKitExample() {
513
722
 
514
723
  const transaction = compileTransaction(transactionMessage);
515
724
 
516
- const result = await signAndSendTransaction({
517
- networkId: NetworkId.SOLANA_MAINNET,
518
- transaction,
519
- });
725
+ // Sign and send using chain-specific hook
726
+ const result = await solana.signAndSendTransaction(transaction);
727
+ console.log("Transaction sent:", result.hash);
520
728
  };
729
+
730
+ return <button onClick={sendTransaction}>Send SOL</button>;
521
731
  }
522
732
  ```
523
733
 
@@ -525,96 +735,40 @@ function SolanaKitExample() {
525
735
 
526
736
  ```tsx
527
737
  import { parseEther, parseGwei, encodeFunctionData } from "viem";
528
- import { useSignAndSendTransaction, NetworkId } from "@phantom/react-sdk";
738
+ import { useEthereum } from "@phantom/react-sdk";
529
739
 
530
740
  function EthereumExample() {
531
- const { signAndSendTransaction } = useSignAndSendTransaction();
741
+ const ethereum = useEthereum();
532
742
 
533
743
  const sendEth = async () => {
534
- const result = await signAndSendTransaction({
535
- networkId: NetworkId.ETHEREUM_MAINNET,
536
- transaction: {
537
- to: "0x742d35Cc6634C0532925a3b8D4C8db86fB5C4A7E",
538
- value: parseEther("1"), // 1 ETH
539
- gas: 21000n,
540
- gasPrice: parseGwei("20"), // 20 gwei
541
- },
744
+ const result = await ethereum.sendTransaction({
745
+ to: "0x742d35Cc6634C0532925a3b8D4C8db86fB5C4A7E",
746
+ value: parseEther("1").toString(), // 1 ETH
747
+ gas: "21000",
748
+ gasPrice: parseGwei("20").toString(), // 20 gwei
542
749
  });
750
+ console.log("ETH sent:", result.hash);
543
751
  };
544
752
 
545
753
  const sendToken = async () => {
546
- const result = await signAndSendTransaction({
547
- networkId: NetworkId.ETHEREUM_MAINNET,
548
- transaction: {
549
- to: tokenContractAddress,
550
- data: encodeFunctionData({
551
- abi: erc20Abi,
552
- functionName: "transfer",
553
- args: [recipientAddress, parseEther("100")],
554
- }),
555
- gas: 50000n,
556
- maxFeePerGas: parseGwei("30"),
557
- maxPriorityFeePerGas: parseGwei("2"),
558
- },
559
- });
560
- };
561
- }
562
- ```
563
-
564
- ## Advanced Usage
565
-
566
- ### Multi-Chain Application
567
-
568
- ```tsx
569
- import { useSignAndSendTransaction, NetworkId } from "@phantom/react-sdk";
570
- import { VersionedTransaction, TransactionMessage, SystemProgram, PublicKey, Connection } from "@solana/web3.js";
571
- import { parseEther } from "viem";
572
-
573
- function MultiChainWallet() {
574
- const { signAndSendTransaction } = useSignAndSendTransaction();
575
-
576
- const sendSolana = async () => {
577
- // Get recent blockhash
578
- const connection = new Connection("https://api.mainnet-beta.solana.com");
579
- const { blockhash } = await connection.getLatestBlockhash();
580
-
581
- // Create transfer instruction
582
- const transferInstruction = SystemProgram.transfer({
583
- fromPubkey: new PublicKey(solanaAddress),
584
- toPubkey: new PublicKey(recipient),
585
- lamports: 1000000,
586
- });
587
-
588
- // Create VersionedTransaction
589
- const messageV0 = new TransactionMessage({
590
- payerKey: new PublicKey(solanaAddress),
591
- recentBlockhash: blockhash,
592
- instructions: [transferInstruction],
593
- }).compileToV0Message();
594
-
595
- const transaction = new VersionedTransaction(messageV0);
596
-
597
- return await signAndSendTransaction({
598
- networkId: NetworkId.SOLANA_MAINNET,
599
- transaction,
600
- });
601
- };
602
-
603
- const sendEthereum = async () => {
604
- return await signAndSendTransaction({
605
- networkId: NetworkId.ETHEREUM_MAINNET,
606
- transaction: {
607
- to: recipient,
608
- value: parseEther("0.1"),
609
- gas: 21000n,
610
- },
754
+ const result = await ethereum.sendTransaction({
755
+ to: tokenContractAddress,
756
+ data: encodeFunctionData({
757
+ abi: erc20Abi,
758
+ functionName: "transfer",
759
+ args: [recipientAddress, parseEther("100")],
760
+ }),
761
+ gas: "50000",
762
+ maxFeePerGas: parseGwei("30").toString(),
763
+ maxPriorityFeePerGas: parseGwei("2").toString(),
611
764
  });
765
+ console.log("Token sent:", result.hash);
612
766
  };
613
767
 
614
768
  return (
615
769
  <div>
616
- <button onClick={sendSolana}>Send SOL</button>
617
- <button onClick={sendEthereum}>Send ETH</button>
770
+ <button onClick={sendEth}>Send ETH</button>
771
+ <button onClick={sendToken}>Send Token</button>
618
772
  </div>
619
773
  );
620
774
  }
@@ -630,8 +784,9 @@ Quick reference of all available hooks:
630
784
  | `useAccounts` | Get wallet addresses | `WalletAddress[]` or `null` |
631
785
  | `useIsExtensionInstalled` | Check extension status | `{ isLoading, isInstalled }` |
632
786
  | `useDisconnect` | Disconnect from wallet | `{ disconnect, isDisconnecting }` |
633
- | `useSignMessage` | Sign text messages | `{ signMessage, isSigning, error }` |
634
- | `useSignAndSendTransaction` | Sign and send transactions | `{ signAndSendTransaction, isSigning, error }` |
787
+ | `useAutoConfirm` | Auto-confirm management (injected only) | `{ enable, disable, status, supportedChains, ... }` |
788
+ | `useSolana` | Solana chain operations | `{ signMessage, signAndSendTransaction, ... }` |
789
+ | `useEthereum` | Ethereum chain operations | `{ signPersonalMessage, sendTransaction, ... }`|
635
790
  | `usePhantom` | Get provider context | `{ isConnected, isReady }` |
636
791
 
637
792
  ## Configuration Reference
@@ -719,4 +874,4 @@ interface DebugMessage {
719
874
  }
720
875
  ```
721
876
 
722
- For more details, examples, and bundle optimization tips, see the [@phantom/browser-sdk documentation](../browser-sdk/README.md).
877
+ For more details and examples, see the [@phantom/browser-sdk documentation](../browser-sdk/README.md).