@phantom/react-sdk 1.0.0-beta.2 → 1.0.0-beta.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.
package/README.md CHANGED
@@ -94,9 +94,8 @@ function App() {
94
94
  <PhantomProvider
95
95
  config={{
96
96
  providerType: "embedded",
97
- embeddedWalletType: "app-wallet", // or 'user-wallet'
97
+ appId: "your-app-id", // Get your app ID from phantom.com/portal
98
98
  addressTypes: [AddressType.solana, AddressType.ethereum],
99
- apiBaseUrl: "https://api.phantom.app/v1/wallets",
100
99
  }}
101
100
  >
102
101
  <YourApp />
@@ -181,26 +180,7 @@ Uses the Phantom browser extension installed by the user.
181
180
 
182
181
  Creates non-custodial wallets embedded in your application.
183
182
 
184
- #### App Wallet (Recommended for most apps)
185
-
186
- - **New wallets** created per application
187
- - **Unfunded** by default - you need to fund them
188
- - **Independent** from user's existing Phantom wallet
189
-
190
- ```tsx
191
- <PhantomProvider
192
- config={{
193
- providerType: "embedded",
194
- embeddedWalletType: "app-wallet",
195
- addressTypes: [AddressType.solana],
196
- apiBaseUrl: "https://api.phantom.app/v1/wallets",
197
- }}
198
- >
199
- <YourApp />
200
- </PhantomProvider>
201
- ```
202
-
203
- #### User Wallet (For existing Phantom users)
183
+ #### User Wallet
204
184
 
205
185
  - **Uses Phantom authentication** - user logs in with existing account
206
186
  - **Potentially funded** - brings existing wallet balance
@@ -210,41 +190,14 @@ Creates non-custodial wallets embedded in your application.
210
190
  <PhantomProvider
211
191
  config={{
212
192
  providerType: "embedded",
213
- embeddedWalletType: "user-wallet",
193
+ appId: "your-app-id",
214
194
  addressTypes: [AddressType.solana, AddressType.ethereum],
215
- apiBaseUrl: "https://api.phantom.app/v1/wallets",
216
- }}
217
- >
218
- <YourApp />
219
- </PhantomProvider>
220
- ```
221
-
222
- ## Solana Provider Configuration
223
-
224
- When using `AddressType.solana`, you can choose between two Solana libraries:
225
-
226
- ```tsx
227
- <PhantomProvider
228
- config={{
229
- providerType: "embedded",
230
- addressTypes: [AddressType.solana],
231
- solanaProvider: "web3js", // or 'kit'
232
- apiBaseUrl: "https://api.phantom.app/v1/wallets",
233
195
  }}
234
196
  >
235
197
  <YourApp />
236
198
  </PhantomProvider>
237
199
  ```
238
200
 
239
- **Provider Options:**
240
-
241
- - `'web3js'` (default) - Uses `@solana/web3.js` library
242
- - `'kit'` - Uses `@solana/kit` library (modern, TypeScript-first)
243
-
244
- **When to use each:**
245
-
246
- - **@solana/web3.js**: Better ecosystem compatibility, wider community support
247
- - **@solana/kit**: Better TypeScript support, modern architecture, smaller bundle size
248
201
 
249
202
  ## Available Hooks
250
203
 
@@ -392,7 +345,7 @@ function SolanaOperations() {
392
345
 
393
346
  // Sign and send
394
347
  const result = await solana.signAndSendTransaction(transaction);
395
- console.log("Transaction sent:", result.hash);
348
+ console.log("Transaction sent:", result.signature);
396
349
  };
397
350
 
398
351
  const switchNetwork = async () => {
@@ -687,7 +640,7 @@ function SolanaExample() {
687
640
 
688
641
  // Sign and send using chain-specific hook
689
642
  const result = await solana.signAndSendTransaction(transaction);
690
- console.log("Transaction sent:", result.hash);
643
+ console.log("Transaction sent:", result.signature);
691
644
  };
692
645
 
693
646
  return <button onClick={sendTransaction}>Send SOL</button>;
@@ -726,7 +679,7 @@ function SolanaKitExample() {
726
679
 
727
680
  // Sign and send using chain-specific hook
728
681
  const result = await solana.signAndSendTransaction(transaction);
729
- console.log("Transaction sent:", result.hash);
682
+ console.log("Transaction sent:", result.signature);
730
683
  };
731
684
 
732
685
  return <button onClick={sendTransaction}>Send SOL</button>;
@@ -799,15 +752,16 @@ interface PhantomSDKConfig {
799
752
  addressTypes?: [AddressType, ...AddressType[]]; // Networks to enable (e.g., [AddressType.solana])
800
753
 
801
754
  // Required for embedded provider only
802
- apiBaseUrl?: string; // Phantom API base URL
803
- appId: string; // Your app ID
755
+ appId: string; // Your app ID from phantom.com/portal (required for embedded provider)
756
+
757
+ // Optional configuration
758
+ apiBaseUrl?: string; // Phantom API base URL (optional, has default)
804
759
  authOptions?: {
805
- authUrl?: string; // Custom auth URL (optional)
806
- redirectUrl?: string; // Custom redirect URL (optional)
760
+ authUrl?: string; // Custom auth URL (optional, defaults to "https://connect.phantom.app/login")
761
+ redirectUrl?: string; // Custom redirect URL after authentication (optional)
807
762
  };
808
- embeddedWalletType?: "app-wallet" | "user-wallet"; // Wallet type
809
- solanaProvider?: "web3js" | "kit"; // Solana library choice (default: 'web3js')
810
- autoConnect?: boolean; // Auto-connect to existing session on SDK instantiation (default: true for embedded, false for injected)
763
+ embeddedWalletType?: "user-wallet"; // Wallet type (optional, defaults to "user-wallet", currently the only supported type)
764
+ autoConnect?: boolean; // Auto-connect to existing session on SDK instantiation (optional, defaults to true for embedded, false for injected)
811
765
  }
812
766
  ```
813
767
 
@@ -839,6 +793,7 @@ function App() {
839
793
  // SDK configuration - static, won't change when debug settings change
840
794
  const config: PhantomSDKConfig = {
841
795
  providerType: "embedded",
796
+ appId: "your-app-id",
842
797
  // ... other config
843
798
  };
844
799
 
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ import { ReactNode } from 'react';
3
3
  import { BrowserSDKConfig, DebugConfig, AuthOptions, BrowserSDK, WalletAddress, AutoConfirmEnableParams, AutoConfirmResult, AutoConfirmSupportedChainsResult } from '@phantom/browser-sdk';
4
4
  export { AddressType, AutoConfirmEnableParams, AutoConfirmResult, AutoConfirmSupportedChainsResult, DebugLevel, DebugMessage, NetworkId, SignedTransaction, WalletAddress, debug } from '@phantom/browser-sdk';
5
5
  import * as _phantom_embedded_provider_core from '@phantom/embedded-provider-core';
6
- import { ISolanaChain, IEthereumChain, EthTransactionRequest } from '@phantom/chains';
6
+ import * as _phantom_chains from '@phantom/chains';
7
7
  export { EthTransactionRequest, IEthereumChain, ISolanaChain } from '@phantom/chains';
8
8
 
9
9
  interface PhantomSDKConfig extends BrowserSDKConfig {
@@ -16,7 +16,7 @@ interface ConnectOptions {
16
16
  authOptions?: AuthOptions;
17
17
  }
18
18
  interface PhantomContextValue {
19
- sdk: BrowserSDK | null;
19
+ sdk: BrowserSDK;
20
20
  isConnected: boolean;
21
21
  isConnecting: boolean;
22
22
  connectError: Error | null;
@@ -72,51 +72,21 @@ declare function useAutoConfirm(): UseAutoConfirmResult;
72
72
  /**
73
73
  * Hook for Solana chain operations
74
74
  *
75
- * @returns Solana chain interface and convenient methods
75
+ * @returns Solana chain interface with connection enforcement
76
76
  */
77
77
  declare function useSolana(): {
78
- solana: ISolanaChain | null;
79
- signMessage: (message: string | Uint8Array) => Promise<{
80
- signature: Uint8Array;
81
- publicKey: string;
82
- }>;
83
- signTransaction: <T>(transaction: T) => Promise<T>;
84
- signAndSendTransaction: <T>(transaction: T) => Promise<{
85
- signature: string;
86
- }>;
87
- connect: (options?: {
88
- onlyIfTrusted?: boolean;
89
- }) => Promise<{
90
- publicKey: string;
91
- }>;
92
- disconnect: () => Promise<void>;
93
- switchNetwork: (network: "mainnet" | "devnet") => Promise<void | undefined>;
94
- getPublicKey: () => Promise<string | null>;
78
+ solana: _phantom_chains.ISolanaChain;
95
79
  isAvailable: boolean;
96
- isConnected: boolean;
97
80
  };
98
81
 
99
82
  /**
100
83
  * Hook for Ethereum chain operations
101
84
  *
102
- * @returns Ethereum chain interface and convenient methods
85
+ * @returns Ethereum chain interface with connection enforcement
103
86
  */
104
87
  declare function useEthereum(): {
105
- ethereum: IEthereumChain | null;
106
- request: <T = any>(args: {
107
- method: string;
108
- params?: unknown[];
109
- }) => Promise<T>;
110
- signPersonalMessage: (message: string, address: string) => Promise<string>;
111
- signMessage: (message: string) => Promise<string>;
112
- signTransaction: (transaction: EthTransactionRequest) => Promise<string>;
113
- signTypedData: (typedData: any) => Promise<string>;
114
- sendTransaction: (transaction: EthTransactionRequest) => Promise<string>;
115
- switchChain: (chainId: number) => Promise<void>;
116
- getChainId: () => Promise<number>;
117
- getAccounts: () => Promise<string[]>;
88
+ ethereum: _phantom_chains.IEthereumChain;
118
89
  isAvailable: boolean;
119
- isConnected: boolean;
120
90
  };
121
91
 
122
92
  type ProviderType = "injected" | "embedded";
package/dist/index.js CHANGED
@@ -68,9 +68,8 @@ function PhantomProvider({ children, config, debugConfig }) {
68
68
  memoizedConfig.providerType || null
69
69
  );
70
70
  const [isPhantomAvailable, setIsPhantomAvailable] = (0, import_react.useState)(false);
71
- const [sdk, setSdk] = (0, import_react.useState)(null);
71
+ const sdk = (0, import_react.useMemo)(() => new import_browser_sdk.BrowserSDK(memoizedConfig), [memoizedConfig]);
72
72
  (0, import_react.useEffect)(() => {
73
- const sdkInstance = new import_browser_sdk.BrowserSDK(memoizedConfig);
74
73
  const handleConnectStart = () => {
75
74
  setIsConnecting(true);
76
75
  setConnectError(null);
@@ -79,15 +78,15 @@ function PhantomProvider({ children, config, debugConfig }) {
79
78
  try {
80
79
  setIsConnected(true);
81
80
  setIsConnecting(false);
82
- const providerInfo = sdkInstance.getCurrentProviderInfo();
81
+ const providerInfo = sdk.getCurrentProviderInfo();
83
82
  setCurrentProviderType(providerInfo?.type || null);
84
- const addrs = await sdkInstance.getAddresses();
83
+ const addrs = await sdk.getAddresses();
85
84
  setAddresses(addrs);
86
- setWalletId(sdkInstance.getWalletId());
85
+ setWalletId(sdk.getWalletId());
87
86
  } catch (err) {
88
87
  console.error("Error connecting:", err);
89
88
  try {
90
- await sdkInstance.disconnect();
89
+ await sdk.disconnect();
91
90
  } catch (err2) {
92
91
  console.error("Error disconnecting:", err2);
93
92
  }
@@ -105,18 +104,17 @@ function PhantomProvider({ children, config, debugConfig }) {
105
104
  setAddresses([]);
106
105
  setWalletId(null);
107
106
  };
108
- sdkInstance.on("connect_start", handleConnectStart);
109
- sdkInstance.on("connect", handleConnect);
110
- sdkInstance.on("connect_error", handleConnectError);
111
- sdkInstance.on("disconnect", handleDisconnect);
112
- setSdk(sdkInstance);
107
+ sdk.on("connect_start", handleConnectStart);
108
+ sdk.on("connect", handleConnect);
109
+ sdk.on("connect_error", handleConnectError);
110
+ sdk.on("disconnect", handleDisconnect);
113
111
  return () => {
114
- sdkInstance.off("connect_start", handleConnectStart);
115
- sdkInstance.off("connect", handleConnect);
116
- sdkInstance.off("connect_error", handleConnectError);
117
- sdkInstance.off("disconnect", handleDisconnect);
112
+ sdk.off("connect_start", handleConnectStart);
113
+ sdk.off("connect", handleConnect);
114
+ sdk.off("connect_error", handleConnectError);
115
+ sdk.off("disconnect", handleDisconnect);
118
116
  };
119
- }, [memoizedConfig]);
117
+ }, [sdk]);
120
118
  (0, import_react.useEffect)(() => {
121
119
  if (!sdk || !debugConfig)
122
120
  return;
@@ -353,187 +351,24 @@ function useAutoConfirm() {
353
351
  }
354
352
 
355
353
  // src/hooks/useSolana.ts
356
- var import_react5 = require("react");
357
354
  function useSolana() {
358
355
  const { sdk, isConnected } = usePhantom();
359
- const getSolanaChain = (0, import_react5.useCallback)(() => {
360
- if (!sdk)
361
- throw new Error("Phantom SDK not initialized.");
362
- if (!sdk.isConnected())
363
- throw new Error("Phantom SDK not connected. Call connect() first.");
364
- return sdk.solana;
365
- }, [sdk]);
366
- const solanaChain = (0, import_react5.useMemo)(() => {
367
- if (!sdk || !isConnected)
368
- return null;
369
- try {
370
- return sdk.solana;
371
- } catch {
372
- return null;
373
- }
374
- }, [sdk, isConnected]);
375
- const signMessage = (0, import_react5.useCallback)(
376
- async (message) => {
377
- const chain = getSolanaChain();
378
- return chain.signMessage(message);
379
- },
380
- [getSolanaChain]
381
- );
382
- const signTransaction = (0, import_react5.useCallback)(
383
- async (transaction) => {
384
- const chain = getSolanaChain();
385
- return chain.signTransaction(transaction);
386
- },
387
- [getSolanaChain]
388
- );
389
- const signAndSendTransaction = (0, import_react5.useCallback)(
390
- async (transaction) => {
391
- const chain = getSolanaChain();
392
- return chain.signAndSendTransaction(transaction);
393
- },
394
- [getSolanaChain]
395
- );
396
- const connect = (0, import_react5.useCallback)(
397
- async (options) => {
398
- const chain = getSolanaChain();
399
- return chain.connect(options);
400
- },
401
- [getSolanaChain]
402
- );
403
- const disconnect = (0, import_react5.useCallback)(async () => {
404
- const chain = getSolanaChain();
405
- return chain.disconnect();
406
- }, [getSolanaChain]);
407
- const switchNetwork = (0, import_react5.useCallback)(
408
- async (network) => {
409
- const chain = getSolanaChain();
410
- return chain.switchNetwork?.(network);
411
- },
412
- [getSolanaChain]
413
- );
414
- const getPublicKey = (0, import_react5.useCallback)(async () => {
415
- if (!sdk || !sdk.isConnected())
416
- return null;
417
- return sdk.solana.getPublicKey();
418
- }, [sdk]);
419
356
  return {
420
- // Chain instance for advanced usage
421
- solana: solanaChain,
422
- // Convenient methods
423
- signMessage,
424
- signTransaction,
425
- signAndSendTransaction,
426
- connect,
427
- disconnect,
428
- switchNetwork,
429
- getPublicKey,
357
+ // Chain instance with connection enforcement for signing methods
358
+ solana: sdk.solana,
430
359
  // State
431
- isAvailable: !!solanaChain,
432
- isConnected: solanaChain?.isConnected() ?? false
360
+ isAvailable: !!isConnected
433
361
  };
434
362
  }
435
363
 
436
364
  // src/hooks/useEthereum.ts
437
- var import_react6 = require("react");
438
365
  function useEthereum() {
439
366
  const { sdk, isConnected } = usePhantom();
440
- const getEthereumChain = (0, import_react6.useCallback)(() => {
441
- if (!sdk)
442
- throw new Error("Phantom SDK not initialized.");
443
- if (!sdk.isConnected())
444
- throw new Error("Phantom SDK not connected. Call connect() first.");
445
- return sdk.ethereum;
446
- }, [sdk]);
447
- const ethereumChain = (0, import_react6.useMemo)(() => {
448
- if (!sdk || !isConnected)
449
- return null;
450
- try {
451
- return sdk.ethereum;
452
- } catch {
453
- return null;
454
- }
455
- }, [sdk, isConnected]);
456
- const request = (0, import_react6.useCallback)(
457
- async (args) => {
458
- const chain = getEthereumChain();
459
- return chain.request(args);
460
- },
461
- [getEthereumChain]
462
- );
463
- const signPersonalMessage = (0, import_react6.useCallback)(
464
- async (message, address) => {
465
- return request({
466
- method: "personal_sign",
467
- params: [message, address]
468
- });
469
- },
470
- [request]
471
- );
472
- const signTransaction = (0, import_react6.useCallback)(
473
- async (transaction) => {
474
- const chain = getEthereumChain();
475
- return chain.signTransaction(transaction);
476
- },
477
- [getEthereumChain]
478
- );
479
- const sendTransaction = (0, import_react6.useCallback)(
480
- async (transaction) => {
481
- const chain = getEthereumChain();
482
- return chain.sendTransaction(transaction);
483
- },
484
- [getEthereumChain]
485
- );
486
- const switchChain = (0, import_react6.useCallback)(
487
- async (chainId) => {
488
- const chain = getEthereumChain();
489
- return chain.switchChain(chainId);
490
- },
491
- [getEthereumChain]
492
- );
493
- const getChainId = (0, import_react6.useCallback)(async () => {
494
- const chain = getEthereumChain();
495
- return chain.getChainId();
496
- }, [getEthereumChain]);
497
- const getAccounts = (0, import_react6.useCallback)(async () => {
498
- const chain = getEthereumChain();
499
- return chain.getAccounts();
500
- }, [getEthereumChain]);
501
- const signMessage = (0, import_react6.useCallback)(
502
- async (message) => {
503
- return request({
504
- method: "eth_sign",
505
- params: [await getAccounts().then((accounts) => accounts[0]), message]
506
- });
507
- },
508
- [request, getAccounts]
509
- );
510
- const signTypedData = (0, import_react6.useCallback)(
511
- async (typedData) => {
512
- const accounts = await getAccounts();
513
- return request({
514
- method: "eth_signTypedData_v4",
515
- params: [accounts[0], JSON.stringify(typedData)]
516
- });
517
- },
518
- [request, getAccounts]
519
- );
520
367
  return {
521
- // Chain instance for advanced usage
522
- ethereum: ethereumChain,
523
- // Standard EIP-1193 interface
524
- request,
525
- // Convenient methods
526
- signPersonalMessage,
527
- signMessage,
528
- signTransaction,
529
- signTypedData,
530
- sendTransaction,
531
- switchChain,
532
- getChainId,
533
- getAccounts,
368
+ // Chain instance with connection enforcement for signing methods
369
+ ethereum: sdk.ethereum,
534
370
  // State
535
- isAvailable: !!ethereumChain,
536
- isConnected: ethereumChain?.isConnected() ?? false
371
+ isAvailable: !!isConnected
537
372
  };
538
373
  }
539
374
 
package/dist/index.mjs CHANGED
@@ -20,9 +20,8 @@ function PhantomProvider({ children, config, debugConfig }) {
20
20
  memoizedConfig.providerType || null
21
21
  );
22
22
  const [isPhantomAvailable, setIsPhantomAvailable] = useState(false);
23
- const [sdk, setSdk] = useState(null);
23
+ const sdk = useMemo(() => new BrowserSDK(memoizedConfig), [memoizedConfig]);
24
24
  useEffect(() => {
25
- const sdkInstance = new BrowserSDK(memoizedConfig);
26
25
  const handleConnectStart = () => {
27
26
  setIsConnecting(true);
28
27
  setConnectError(null);
@@ -31,15 +30,15 @@ function PhantomProvider({ children, config, debugConfig }) {
31
30
  try {
32
31
  setIsConnected(true);
33
32
  setIsConnecting(false);
34
- const providerInfo = sdkInstance.getCurrentProviderInfo();
33
+ const providerInfo = sdk.getCurrentProviderInfo();
35
34
  setCurrentProviderType(providerInfo?.type || null);
36
- const addrs = await sdkInstance.getAddresses();
35
+ const addrs = await sdk.getAddresses();
37
36
  setAddresses(addrs);
38
- setWalletId(sdkInstance.getWalletId());
37
+ setWalletId(sdk.getWalletId());
39
38
  } catch (err) {
40
39
  console.error("Error connecting:", err);
41
40
  try {
42
- await sdkInstance.disconnect();
41
+ await sdk.disconnect();
43
42
  } catch (err2) {
44
43
  console.error("Error disconnecting:", err2);
45
44
  }
@@ -57,18 +56,17 @@ function PhantomProvider({ children, config, debugConfig }) {
57
56
  setAddresses([]);
58
57
  setWalletId(null);
59
58
  };
60
- sdkInstance.on("connect_start", handleConnectStart);
61
- sdkInstance.on("connect", handleConnect);
62
- sdkInstance.on("connect_error", handleConnectError);
63
- sdkInstance.on("disconnect", handleDisconnect);
64
- setSdk(sdkInstance);
59
+ sdk.on("connect_start", handleConnectStart);
60
+ sdk.on("connect", handleConnect);
61
+ sdk.on("connect_error", handleConnectError);
62
+ sdk.on("disconnect", handleDisconnect);
65
63
  return () => {
66
- sdkInstance.off("connect_start", handleConnectStart);
67
- sdkInstance.off("connect", handleConnect);
68
- sdkInstance.off("connect_error", handleConnectError);
69
- sdkInstance.off("disconnect", handleDisconnect);
64
+ sdk.off("connect_start", handleConnectStart);
65
+ sdk.off("connect", handleConnect);
66
+ sdk.off("connect_error", handleConnectError);
67
+ sdk.off("disconnect", handleDisconnect);
70
68
  };
71
- }, [memoizedConfig]);
69
+ }, [sdk]);
72
70
  useEffect(() => {
73
71
  if (!sdk || !debugConfig)
74
72
  return;
@@ -305,187 +303,24 @@ function useAutoConfirm() {
305
303
  }
306
304
 
307
305
  // src/hooks/useSolana.ts
308
- import { useCallback as useCallback4, useMemo as useMemo2 } from "react";
309
306
  function useSolana() {
310
307
  const { sdk, isConnected } = usePhantom();
311
- const getSolanaChain = useCallback4(() => {
312
- if (!sdk)
313
- throw new Error("Phantom SDK not initialized.");
314
- if (!sdk.isConnected())
315
- throw new Error("Phantom SDK not connected. Call connect() first.");
316
- return sdk.solana;
317
- }, [sdk]);
318
- const solanaChain = useMemo2(() => {
319
- if (!sdk || !isConnected)
320
- return null;
321
- try {
322
- return sdk.solana;
323
- } catch {
324
- return null;
325
- }
326
- }, [sdk, isConnected]);
327
- const signMessage = useCallback4(
328
- async (message) => {
329
- const chain = getSolanaChain();
330
- return chain.signMessage(message);
331
- },
332
- [getSolanaChain]
333
- );
334
- const signTransaction = useCallback4(
335
- async (transaction) => {
336
- const chain = getSolanaChain();
337
- return chain.signTransaction(transaction);
338
- },
339
- [getSolanaChain]
340
- );
341
- const signAndSendTransaction = useCallback4(
342
- async (transaction) => {
343
- const chain = getSolanaChain();
344
- return chain.signAndSendTransaction(transaction);
345
- },
346
- [getSolanaChain]
347
- );
348
- const connect = useCallback4(
349
- async (options) => {
350
- const chain = getSolanaChain();
351
- return chain.connect(options);
352
- },
353
- [getSolanaChain]
354
- );
355
- const disconnect = useCallback4(async () => {
356
- const chain = getSolanaChain();
357
- return chain.disconnect();
358
- }, [getSolanaChain]);
359
- const switchNetwork = useCallback4(
360
- async (network) => {
361
- const chain = getSolanaChain();
362
- return chain.switchNetwork?.(network);
363
- },
364
- [getSolanaChain]
365
- );
366
- const getPublicKey = useCallback4(async () => {
367
- if (!sdk || !sdk.isConnected())
368
- return null;
369
- return sdk.solana.getPublicKey();
370
- }, [sdk]);
371
308
  return {
372
- // Chain instance for advanced usage
373
- solana: solanaChain,
374
- // Convenient methods
375
- signMessage,
376
- signTransaction,
377
- signAndSendTransaction,
378
- connect,
379
- disconnect,
380
- switchNetwork,
381
- getPublicKey,
309
+ // Chain instance with connection enforcement for signing methods
310
+ solana: sdk.solana,
382
311
  // State
383
- isAvailable: !!solanaChain,
384
- isConnected: solanaChain?.isConnected() ?? false
312
+ isAvailable: !!isConnected
385
313
  };
386
314
  }
387
315
 
388
316
  // src/hooks/useEthereum.ts
389
- import { useCallback as useCallback5, useMemo as useMemo3 } from "react";
390
317
  function useEthereum() {
391
318
  const { sdk, isConnected } = usePhantom();
392
- const getEthereumChain = useCallback5(() => {
393
- if (!sdk)
394
- throw new Error("Phantom SDK not initialized.");
395
- if (!sdk.isConnected())
396
- throw new Error("Phantom SDK not connected. Call connect() first.");
397
- return sdk.ethereum;
398
- }, [sdk]);
399
- const ethereumChain = useMemo3(() => {
400
- if (!sdk || !isConnected)
401
- return null;
402
- try {
403
- return sdk.ethereum;
404
- } catch {
405
- return null;
406
- }
407
- }, [sdk, isConnected]);
408
- const request = useCallback5(
409
- async (args) => {
410
- const chain = getEthereumChain();
411
- return chain.request(args);
412
- },
413
- [getEthereumChain]
414
- );
415
- const signPersonalMessage = useCallback5(
416
- async (message, address) => {
417
- return request({
418
- method: "personal_sign",
419
- params: [message, address]
420
- });
421
- },
422
- [request]
423
- );
424
- const signTransaction = useCallback5(
425
- async (transaction) => {
426
- const chain = getEthereumChain();
427
- return chain.signTransaction(transaction);
428
- },
429
- [getEthereumChain]
430
- );
431
- const sendTransaction = useCallback5(
432
- async (transaction) => {
433
- const chain = getEthereumChain();
434
- return chain.sendTransaction(transaction);
435
- },
436
- [getEthereumChain]
437
- );
438
- const switchChain = useCallback5(
439
- async (chainId) => {
440
- const chain = getEthereumChain();
441
- return chain.switchChain(chainId);
442
- },
443
- [getEthereumChain]
444
- );
445
- const getChainId = useCallback5(async () => {
446
- const chain = getEthereumChain();
447
- return chain.getChainId();
448
- }, [getEthereumChain]);
449
- const getAccounts = useCallback5(async () => {
450
- const chain = getEthereumChain();
451
- return chain.getAccounts();
452
- }, [getEthereumChain]);
453
- const signMessage = useCallback5(
454
- async (message) => {
455
- return request({
456
- method: "eth_sign",
457
- params: [await getAccounts().then((accounts) => accounts[0]), message]
458
- });
459
- },
460
- [request, getAccounts]
461
- );
462
- const signTypedData = useCallback5(
463
- async (typedData) => {
464
- const accounts = await getAccounts();
465
- return request({
466
- method: "eth_signTypedData_v4",
467
- params: [accounts[0], JSON.stringify(typedData)]
468
- });
469
- },
470
- [request, getAccounts]
471
- );
472
319
  return {
473
- // Chain instance for advanced usage
474
- ethereum: ethereumChain,
475
- // Standard EIP-1193 interface
476
- request,
477
- // Convenient methods
478
- signPersonalMessage,
479
- signMessage,
480
- signTransaction,
481
- signTypedData,
482
- sendTransaction,
483
- switchChain,
484
- getChainId,
485
- getAccounts,
320
+ // Chain instance with connection enforcement for signing methods
321
+ ethereum: sdk.ethereum,
486
322
  // State
487
- isAvailable: !!ethereumChain,
488
- isConnected: ethereumChain?.isConnected() ?? false
323
+ isAvailable: !!isConnected
489
324
  };
490
325
  }
491
326
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phantom/react-sdk",
3
- "version": "1.0.0-beta.2",
3
+ "version": "1.0.0-beta.4",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",
@@ -26,9 +26,9 @@
26
26
  "prettier": "prettier --write \"src/**/*.{ts,tsx}\""
27
27
  },
28
28
  "dependencies": {
29
- "@phantom/browser-sdk": "^1.0.0-beta.2",
30
- "@phantom/chains": "^1.0.0-beta.2",
31
- "@phantom/constants": "^1.0.0-beta.2"
29
+ "@phantom/browser-sdk": "^1.0.0-beta.4",
30
+ "@phantom/chains": "^1.0.0-beta.4",
31
+ "@phantom/constants": "^1.0.0-beta.4"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@testing-library/dom": "^10.4.0",