@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 +15 -60
- package/dist/index.d.ts +6 -36
- package/dist/index.js +20 -185
- package/dist/index.mjs +20 -185
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -94,9 +94,8 @@ function App() {
|
|
|
94
94
|
<PhantomProvider
|
|
95
95
|
config={{
|
|
96
96
|
providerType: "embedded",
|
|
97
|
-
|
|
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
|
-
####
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
803
|
-
|
|
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?: "
|
|
809
|
-
|
|
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
|
|
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
|
|
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
|
|
75
|
+
* @returns Solana chain interface with connection enforcement
|
|
76
76
|
*/
|
|
77
77
|
declare function useSolana(): {
|
|
78
|
-
solana: ISolanaChain
|
|
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
|
|
85
|
+
* @returns Ethereum chain interface with connection enforcement
|
|
103
86
|
*/
|
|
104
87
|
declare function useEthereum(): {
|
|
105
|
-
ethereum: IEthereumChain
|
|
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
|
|
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 =
|
|
81
|
+
const providerInfo = sdk.getCurrentProviderInfo();
|
|
83
82
|
setCurrentProviderType(providerInfo?.type || null);
|
|
84
|
-
const addrs = await
|
|
83
|
+
const addrs = await sdk.getAddresses();
|
|
85
84
|
setAddresses(addrs);
|
|
86
|
-
setWalletId(
|
|
85
|
+
setWalletId(sdk.getWalletId());
|
|
87
86
|
} catch (err) {
|
|
88
87
|
console.error("Error connecting:", err);
|
|
89
88
|
try {
|
|
90
|
-
await
|
|
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
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
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
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
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
|
-
}, [
|
|
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
|
|
421
|
-
solana:
|
|
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: !!
|
|
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
|
|
522
|
-
ethereum:
|
|
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: !!
|
|
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
|
|
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 =
|
|
33
|
+
const providerInfo = sdk.getCurrentProviderInfo();
|
|
35
34
|
setCurrentProviderType(providerInfo?.type || null);
|
|
36
|
-
const addrs = await
|
|
35
|
+
const addrs = await sdk.getAddresses();
|
|
37
36
|
setAddresses(addrs);
|
|
38
|
-
setWalletId(
|
|
37
|
+
setWalletId(sdk.getWalletId());
|
|
39
38
|
} catch (err) {
|
|
40
39
|
console.error("Error connecting:", err);
|
|
41
40
|
try {
|
|
42
|
-
await
|
|
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
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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
|
-
}, [
|
|
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
|
|
373
|
-
solana:
|
|
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: !!
|
|
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
|
|
474
|
-
ethereum:
|
|
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: !!
|
|
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.
|
|
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.
|
|
30
|
-
"@phantom/chains": "^1.0.0-beta.
|
|
31
|
-
"@phantom/constants": "^1.0.0-beta.
|
|
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",
|