@phantom/react-sdk 0.3.4 → 0.3.6
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 +63 -6
- package/dist/index.d.ts +9 -6
- package/dist/index.js +84 -61
- package/dist/index.mjs +99 -76
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -641,7 +641,7 @@ interface PhantomSDKConfig {
|
|
|
641
641
|
providerType: "injected" | "embedded";
|
|
642
642
|
appName?: string; // Optional app name for branding
|
|
643
643
|
appLogo?: string; // Optional app logo URL for branding
|
|
644
|
-
addressTypes?: AddressType[]; // Networks to enable (e.g., [AddressType.solana])
|
|
644
|
+
addressTypes?: [AddressType, ...AddressType[]]; // Networks to enable (e.g., [AddressType.solana])
|
|
645
645
|
|
|
646
646
|
// Required for embedded provider only
|
|
647
647
|
apiBaseUrl?: string; // Phantom API base URL
|
|
@@ -652,13 +652,70 @@ interface PhantomSDKConfig {
|
|
|
652
652
|
};
|
|
653
653
|
embeddedWalletType?: "app-wallet" | "user-wallet"; // Wallet type
|
|
654
654
|
solanaProvider?: "web3js" | "kit"; // Solana library choice (default: 'web3js')
|
|
655
|
+
autoConnect?: boolean; // Auto-connect to existing session on SDK instantiation (default: true for embedded, false for injected)
|
|
656
|
+
}
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
## Debug Configuration
|
|
660
|
+
|
|
661
|
+
The React SDK supports separate debug configuration that can be changed without reinstantiating the underlying SDK, providing better performance.
|
|
662
|
+
|
|
663
|
+
### PhantomDebugConfig Interface
|
|
664
|
+
|
|
665
|
+
```typescript
|
|
666
|
+
interface PhantomDebugConfig {
|
|
667
|
+
enabled?: boolean; // Enable debug logging
|
|
668
|
+
level?: DebugLevel; // Debug level (ERROR, WARN, INFO, DEBUG)
|
|
669
|
+
callback?: DebugCallback; // Custom debug message handler
|
|
670
|
+
}
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
### Using Debug Configuration
|
|
674
|
+
|
|
675
|
+
Pass the `debugConfig` as a separate prop to `PhantomProvider`:
|
|
676
|
+
|
|
677
|
+
```typescript
|
|
678
|
+
import { PhantomProvider, type PhantomSDKConfig, type PhantomDebugConfig, DebugLevel } from "@phantom/react-sdk";
|
|
679
|
+
|
|
680
|
+
function App() {
|
|
681
|
+
const [debugLevel, setDebugLevel] = useState(DebugLevel.INFO);
|
|
682
|
+
const [debugMessages, setDebugMessages] = useState([]);
|
|
655
683
|
|
|
656
|
-
//
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
684
|
+
// SDK configuration - static, won't change when debug settings change
|
|
685
|
+
const config: PhantomSDKConfig = {
|
|
686
|
+
providerType: "embedded",
|
|
687
|
+
organizationId: "your-org-id",
|
|
688
|
+
// ... other config
|
|
689
|
+
};
|
|
690
|
+
|
|
691
|
+
// Debug configuration - separate to avoid SDK reinstantiation
|
|
692
|
+
const debugConfig: PhantomDebugConfig = {
|
|
693
|
+
enabled: true,
|
|
694
|
+
level: debugLevel,
|
|
695
|
+
callback: (message) => {
|
|
696
|
+
setDebugMessages(prev => [...prev, message]);
|
|
697
|
+
}
|
|
661
698
|
};
|
|
699
|
+
|
|
700
|
+
return (
|
|
701
|
+
<PhantomProvider config={config} debugConfig={debugConfig}>
|
|
702
|
+
{/* Your app components */}
|
|
703
|
+
</PhantomProvider>
|
|
704
|
+
);
|
|
705
|
+
}
|
|
706
|
+
```
|
|
707
|
+
|
|
708
|
+
### Debug Message Structure
|
|
709
|
+
|
|
710
|
+
Debug callbacks receive a `DebugMessage` object:
|
|
711
|
+
|
|
712
|
+
```typescript
|
|
713
|
+
interface DebugMessage {
|
|
714
|
+
timestamp: number; // Unix timestamp
|
|
715
|
+
level: DebugLevel; // Message level
|
|
716
|
+
category: string; // Component category
|
|
717
|
+
message: string; // Debug message text
|
|
718
|
+
data?: any; // Additional debug data (optional)
|
|
662
719
|
}
|
|
663
720
|
```
|
|
664
721
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,31 +1,34 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import { BrowserSDKConfig, AuthOptions, BrowserSDK, WalletAddress, SignMessageParams, SignMessageResult, SignAndSendTransactionParams, SignedTransaction } from '@phantom/browser-sdk';
|
|
3
|
+
import { BrowserSDKConfig, DebugConfig, AuthOptions, BrowserSDK, WalletAddress, SignMessageParams, SignMessageResult, SignAndSendTransactionParams, SignedTransaction } from '@phantom/browser-sdk';
|
|
4
4
|
export { AddressType, DebugLevel, DebugMessage, NetworkId, SignAndSendTransactionParams, SignMessageParams, SignMessageResult, SignedTransaction, WalletAddress, debug } from '@phantom/browser-sdk';
|
|
5
5
|
import * as _phantom_embedded_provider_core from '@phantom/embedded-provider-core';
|
|
6
6
|
|
|
7
7
|
interface PhantomSDKConfig extends BrowserSDKConfig {
|
|
8
8
|
}
|
|
9
|
+
interface PhantomDebugConfig extends DebugConfig {
|
|
10
|
+
}
|
|
9
11
|
interface ConnectOptions {
|
|
10
12
|
providerType?: "injected" | "embedded";
|
|
11
13
|
embeddedWalletType?: "app-wallet" | "user-wallet";
|
|
12
14
|
authOptions?: AuthOptions;
|
|
13
15
|
}
|
|
14
16
|
interface PhantomContextValue {
|
|
15
|
-
sdk: BrowserSDK;
|
|
17
|
+
sdk: BrowserSDK | null;
|
|
16
18
|
isConnected: boolean;
|
|
19
|
+
isConnecting: boolean;
|
|
20
|
+
connectError: Error | null;
|
|
17
21
|
addresses: WalletAddress[];
|
|
18
22
|
walletId: string | null;
|
|
19
|
-
error: Error | null;
|
|
20
23
|
currentProviderType: "injected" | "embedded" | null;
|
|
21
24
|
isPhantomAvailable: boolean;
|
|
22
|
-
updateConnectionState: () => Promise<void>;
|
|
23
25
|
}
|
|
24
26
|
interface PhantomProviderProps {
|
|
25
27
|
children: ReactNode;
|
|
26
28
|
config: PhantomSDKConfig;
|
|
29
|
+
debugConfig?: PhantomDebugConfig;
|
|
27
30
|
}
|
|
28
|
-
declare function PhantomProvider({ children, config }: PhantomProviderProps): react_jsx_runtime.JSX.Element;
|
|
31
|
+
declare function PhantomProvider({ children, config, debugConfig }: PhantomProviderProps): react_jsx_runtime.JSX.Element;
|
|
29
32
|
declare function usePhantom(): PhantomContextValue;
|
|
30
33
|
|
|
31
34
|
declare function useConnect(): {
|
|
@@ -63,4 +66,4 @@ declare function useIsExtensionInstalled(): {
|
|
|
63
66
|
|
|
64
67
|
type ProviderType = "injected" | "embedded";
|
|
65
68
|
|
|
66
|
-
export { ConnectOptions, PhantomProvider, PhantomProviderProps, PhantomSDKConfig, ProviderType, useAccounts, useConnect, useDisconnect, useIsExtensionInstalled, usePhantom, useSignAndSendTransaction, useSignMessage };
|
|
69
|
+
export { ConnectOptions, PhantomDebugConfig, PhantomProvider, PhantomProviderProps, PhantomSDKConfig, ProviderType, useAccounts, useConnect, useDisconnect, useIsExtensionInstalled, usePhantom, useSignAndSendTransaction, useSignMessage };
|
package/dist/index.js
CHANGED
|
@@ -50,49 +50,78 @@ var import_react = require("react");
|
|
|
50
50
|
var import_browser_sdk = require("@phantom/browser-sdk");
|
|
51
51
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
52
52
|
var PhantomContext = (0, import_react.createContext)(void 0);
|
|
53
|
-
function PhantomProvider({ children, config }) {
|
|
54
|
-
const sdk = (0, import_react.useMemo)(
|
|
55
|
-
() => new import_browser_sdk.BrowserSDK({
|
|
56
|
-
...config,
|
|
57
|
-
// Use providerType if provided, default to embedded
|
|
58
|
-
providerType: config.providerType || "embedded"
|
|
59
|
-
}),
|
|
60
|
-
[config]
|
|
61
|
-
);
|
|
53
|
+
function PhantomProvider({ children, config, debugConfig }) {
|
|
62
54
|
const [isConnected, setIsConnected] = (0, import_react.useState)(false);
|
|
55
|
+
const [isConnecting, setIsConnecting] = (0, import_react.useState)(false);
|
|
56
|
+
const [connectError, setConnectError] = (0, import_react.useState)(null);
|
|
63
57
|
const [addresses, setAddresses] = (0, import_react.useState)([]);
|
|
64
58
|
const [walletId, setWalletId] = (0, import_react.useState)(null);
|
|
65
|
-
const [error, setError] = (0, import_react.useState)(null);
|
|
66
59
|
const [currentProviderType, setCurrentProviderType] = (0, import_react.useState)(null);
|
|
67
60
|
const [isPhantomAvailable, setIsPhantomAvailable] = (0, import_react.useState)(false);
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
console.error("Error updating connection state:", err);
|
|
84
|
-
setError(err);
|
|
61
|
+
const [sdk, setSdk] = (0, import_react.useState)(null);
|
|
62
|
+
const memoizedConfig = (0, import_react.useMemo)(() => {
|
|
63
|
+
return {
|
|
64
|
+
...config,
|
|
65
|
+
// Use providerType if provided, default to embedded
|
|
66
|
+
providerType: config.providerType || "embedded"
|
|
67
|
+
};
|
|
68
|
+
}, [config]);
|
|
69
|
+
(0, import_react.useEffect)(() => {
|
|
70
|
+
const sdkInstance = new import_browser_sdk.BrowserSDK(memoizedConfig);
|
|
71
|
+
const handleConnectStart = () => {
|
|
72
|
+
setIsConnecting(true);
|
|
73
|
+
setConnectError(null);
|
|
74
|
+
};
|
|
75
|
+
const handleConnect = async () => {
|
|
85
76
|
try {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
77
|
+
setIsConnected(true);
|
|
78
|
+
setIsConnecting(false);
|
|
79
|
+
const providerInfo = sdkInstance.getCurrentProviderInfo();
|
|
80
|
+
setCurrentProviderType(providerInfo?.type || null);
|
|
81
|
+
const addrs = await sdkInstance.getAddresses();
|
|
82
|
+
setAddresses(addrs);
|
|
83
|
+
setWalletId(sdkInstance.getWalletId());
|
|
84
|
+
} catch (err) {
|
|
85
|
+
console.error("Error connecting:", err);
|
|
86
|
+
try {
|
|
87
|
+
await sdkInstance.disconnect();
|
|
88
|
+
} catch (err2) {
|
|
89
|
+
console.error("Error disconnecting:", err2);
|
|
90
|
+
}
|
|
92
91
|
}
|
|
93
|
-
}
|
|
94
|
-
|
|
92
|
+
};
|
|
93
|
+
const handleConnectError = (errorData) => {
|
|
94
|
+
setIsConnecting(false);
|
|
95
|
+
setIsConnected(false);
|
|
96
|
+
setConnectError(new Error(errorData.error || "Connection failed"));
|
|
97
|
+
};
|
|
98
|
+
const handleDisconnect = () => {
|
|
99
|
+
setIsConnected(false);
|
|
100
|
+
setIsConnecting(false);
|
|
101
|
+
setConnectError(null);
|
|
102
|
+
setAddresses([]);
|
|
103
|
+
setWalletId(null);
|
|
104
|
+
};
|
|
105
|
+
sdkInstance.on("connect_start", handleConnectStart);
|
|
106
|
+
sdkInstance.on("connect", handleConnect);
|
|
107
|
+
sdkInstance.on("connect_error", handleConnectError);
|
|
108
|
+
sdkInstance.on("disconnect", handleDisconnect);
|
|
109
|
+
setSdk(sdkInstance);
|
|
110
|
+
return () => {
|
|
111
|
+
sdkInstance.off("connect_start", handleConnectStart);
|
|
112
|
+
sdkInstance.off("connect", handleConnect);
|
|
113
|
+
sdkInstance.off("connect_error", handleConnectError);
|
|
114
|
+
sdkInstance.off("disconnect", handleDisconnect);
|
|
115
|
+
};
|
|
116
|
+
}, [memoizedConfig]);
|
|
117
|
+
(0, import_react.useEffect)(() => {
|
|
118
|
+
if (!sdk || !debugConfig)
|
|
119
|
+
return;
|
|
120
|
+
sdk.configureDebug(debugConfig);
|
|
121
|
+
}, [sdk, debugConfig]);
|
|
95
122
|
(0, import_react.useEffect)(() => {
|
|
123
|
+
if (!sdk)
|
|
124
|
+
return;
|
|
96
125
|
const initialize = async () => {
|
|
97
126
|
try {
|
|
98
127
|
const available = await sdk.waitForPhantomExtension(1e3);
|
|
@@ -101,28 +130,31 @@ function PhantomProvider({ children, config }) {
|
|
|
101
130
|
console.error("Error checking Phantom extension:", err);
|
|
102
131
|
setIsPhantomAvailable(false);
|
|
103
132
|
}
|
|
104
|
-
|
|
133
|
+
if (config.autoConnect !== false) {
|
|
134
|
+
sdk.autoConnect().catch(() => {
|
|
135
|
+
});
|
|
136
|
+
}
|
|
105
137
|
};
|
|
106
138
|
initialize();
|
|
107
|
-
}, [sdk,
|
|
139
|
+
}, [sdk, config.autoConnect]);
|
|
108
140
|
const value = (0, import_react.useMemo)(
|
|
109
141
|
() => ({
|
|
110
142
|
sdk,
|
|
111
143
|
isConnected,
|
|
144
|
+
isConnecting,
|
|
145
|
+
connectError,
|
|
112
146
|
addresses,
|
|
113
|
-
updateConnectionState,
|
|
114
147
|
walletId,
|
|
115
|
-
error,
|
|
116
148
|
currentProviderType,
|
|
117
149
|
isPhantomAvailable
|
|
118
150
|
}),
|
|
119
151
|
[
|
|
120
152
|
sdk,
|
|
121
153
|
isConnected,
|
|
154
|
+
isConnecting,
|
|
155
|
+
connectError,
|
|
122
156
|
addresses,
|
|
123
|
-
updateConnectionState,
|
|
124
157
|
walletId,
|
|
125
|
-
error,
|
|
126
158
|
currentProviderType,
|
|
127
159
|
isPhantomAvailable
|
|
128
160
|
]
|
|
@@ -140,34 +172,26 @@ function usePhantom() {
|
|
|
140
172
|
// src/hooks/useConnect.ts
|
|
141
173
|
var import_react2 = require("react");
|
|
142
174
|
function useConnect() {
|
|
143
|
-
const { sdk,
|
|
144
|
-
const [isConnecting, setIsConnecting] = (0, import_react2.useState)(false);
|
|
145
|
-
const [error, setError] = (0, import_react2.useState)(null);
|
|
175
|
+
const { sdk, isConnecting, connectError, currentProviderType, isPhantomAvailable } = usePhantom();
|
|
146
176
|
const connect = (0, import_react2.useCallback)(
|
|
147
177
|
async (options) => {
|
|
148
178
|
if (!sdk) {
|
|
149
179
|
throw new Error("SDK not initialized");
|
|
150
180
|
}
|
|
151
|
-
setIsConnecting(true);
|
|
152
|
-
setError(null);
|
|
153
181
|
try {
|
|
154
182
|
const result = await sdk.connect(options);
|
|
155
|
-
await updateConnectionState();
|
|
156
183
|
return result;
|
|
157
184
|
} catch (err) {
|
|
158
185
|
console.error("Error connecting to Phantom:", err);
|
|
159
|
-
setError(err);
|
|
160
186
|
throw err;
|
|
161
|
-
} finally {
|
|
162
|
-
setIsConnecting(false);
|
|
163
187
|
}
|
|
164
188
|
},
|
|
165
|
-
[sdk
|
|
189
|
+
[sdk]
|
|
166
190
|
);
|
|
167
191
|
return {
|
|
168
192
|
connect,
|
|
169
193
|
isConnecting,
|
|
170
|
-
error,
|
|
194
|
+
error: connectError,
|
|
171
195
|
currentProviderType,
|
|
172
196
|
isPhantomAvailable
|
|
173
197
|
};
|
|
@@ -176,7 +200,7 @@ function useConnect() {
|
|
|
176
200
|
// src/hooks/useDisconnect.ts
|
|
177
201
|
var import_react3 = require("react");
|
|
178
202
|
function useDisconnect() {
|
|
179
|
-
const { sdk
|
|
203
|
+
const { sdk } = usePhantom();
|
|
180
204
|
const [isDisconnecting, setIsDisconnecting] = (0, import_react3.useState)(false);
|
|
181
205
|
const [error, setError] = (0, import_react3.useState)(null);
|
|
182
206
|
const disconnect = (0, import_react3.useCallback)(async () => {
|
|
@@ -187,14 +211,13 @@ function useDisconnect() {
|
|
|
187
211
|
setError(null);
|
|
188
212
|
try {
|
|
189
213
|
await sdk.disconnect();
|
|
190
|
-
await updateConnectionState();
|
|
191
214
|
} catch (err) {
|
|
192
215
|
setError(err);
|
|
193
216
|
throw err;
|
|
194
217
|
} finally {
|
|
195
218
|
setIsDisconnecting(false);
|
|
196
219
|
}
|
|
197
|
-
}, [sdk
|
|
220
|
+
}, [sdk]);
|
|
198
221
|
return {
|
|
199
222
|
disconnect,
|
|
200
223
|
isDisconnecting,
|
|
@@ -205,7 +228,7 @@ function useDisconnect() {
|
|
|
205
228
|
// src/hooks/useSignMessage.ts
|
|
206
229
|
var import_react4 = require("react");
|
|
207
230
|
function useSignMessage() {
|
|
208
|
-
const { sdk
|
|
231
|
+
const { sdk } = usePhantom();
|
|
209
232
|
const [isSigning, setIsSigning] = (0, import_react4.useState)(false);
|
|
210
233
|
const [error, setError] = (0, import_react4.useState)(null);
|
|
211
234
|
const signMessage = (0, import_react4.useCallback)(
|
|
@@ -213,7 +236,7 @@ function useSignMessage() {
|
|
|
213
236
|
if (!sdk) {
|
|
214
237
|
throw new Error("SDK not initialized");
|
|
215
238
|
}
|
|
216
|
-
if (!isConnected) {
|
|
239
|
+
if (!sdk.isConnected()) {
|
|
217
240
|
throw new Error("Wallet not connected");
|
|
218
241
|
}
|
|
219
242
|
setIsSigning(true);
|
|
@@ -228,7 +251,7 @@ function useSignMessage() {
|
|
|
228
251
|
setIsSigning(false);
|
|
229
252
|
}
|
|
230
253
|
},
|
|
231
|
-
[sdk
|
|
254
|
+
[sdk]
|
|
232
255
|
);
|
|
233
256
|
return {
|
|
234
257
|
signMessage,
|
|
@@ -240,7 +263,7 @@ function useSignMessage() {
|
|
|
240
263
|
// src/hooks/useSignAndSendTransaction.ts
|
|
241
264
|
var import_react5 = require("react");
|
|
242
265
|
function useSignAndSendTransaction() {
|
|
243
|
-
const { sdk
|
|
266
|
+
const { sdk } = usePhantom();
|
|
244
267
|
const [isSigning, setIsSigning] = (0, import_react5.useState)(false);
|
|
245
268
|
const [error, setError] = (0, import_react5.useState)(null);
|
|
246
269
|
const signAndSendTransaction = (0, import_react5.useCallback)(
|
|
@@ -248,7 +271,7 @@ function useSignAndSendTransaction() {
|
|
|
248
271
|
if (!sdk) {
|
|
249
272
|
throw new Error("SDK not initialized");
|
|
250
273
|
}
|
|
251
|
-
if (!isConnected) {
|
|
274
|
+
if (!sdk.isConnected()) {
|
|
252
275
|
throw new Error("Wallet not connected");
|
|
253
276
|
}
|
|
254
277
|
setIsSigning(true);
|
|
@@ -263,7 +286,7 @@ function useSignAndSendTransaction() {
|
|
|
263
286
|
setIsSigning(false);
|
|
264
287
|
}
|
|
265
288
|
},
|
|
266
|
-
[sdk
|
|
289
|
+
[sdk]
|
|
267
290
|
);
|
|
268
291
|
return {
|
|
269
292
|
signAndSendTransaction,
|
package/dist/index.mjs
CHANGED
|
@@ -1,51 +1,80 @@
|
|
|
1
1
|
// src/PhantomProvider.tsx
|
|
2
|
-
import { createContext, useContext, useState, useEffect,
|
|
2
|
+
import { createContext, useContext, useState, useEffect, useMemo } from "react";
|
|
3
3
|
import { BrowserSDK } from "@phantom/browser-sdk";
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
5
5
|
var PhantomContext = createContext(void 0);
|
|
6
|
-
function PhantomProvider({ children, config }) {
|
|
7
|
-
const sdk = useMemo(
|
|
8
|
-
() => new BrowserSDK({
|
|
9
|
-
...config,
|
|
10
|
-
// Use providerType if provided, default to embedded
|
|
11
|
-
providerType: config.providerType || "embedded"
|
|
12
|
-
}),
|
|
13
|
-
[config]
|
|
14
|
-
);
|
|
6
|
+
function PhantomProvider({ children, config, debugConfig }) {
|
|
15
7
|
const [isConnected, setIsConnected] = useState(false);
|
|
8
|
+
const [isConnecting, setIsConnecting] = useState(false);
|
|
9
|
+
const [connectError, setConnectError] = useState(null);
|
|
16
10
|
const [addresses, setAddresses] = useState([]);
|
|
17
11
|
const [walletId, setWalletId] = useState(null);
|
|
18
|
-
const [error, setError] = useState(null);
|
|
19
12
|
const [currentProviderType, setCurrentProviderType] = useState(null);
|
|
20
13
|
const [isPhantomAvailable, setIsPhantomAvailable] = useState(false);
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
console.error("Error updating connection state:", err);
|
|
37
|
-
setError(err);
|
|
14
|
+
const [sdk, setSdk] = useState(null);
|
|
15
|
+
const memoizedConfig = useMemo(() => {
|
|
16
|
+
return {
|
|
17
|
+
...config,
|
|
18
|
+
// Use providerType if provided, default to embedded
|
|
19
|
+
providerType: config.providerType || "embedded"
|
|
20
|
+
};
|
|
21
|
+
}, [config]);
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
const sdkInstance = new BrowserSDK(memoizedConfig);
|
|
24
|
+
const handleConnectStart = () => {
|
|
25
|
+
setIsConnecting(true);
|
|
26
|
+
setConnectError(null);
|
|
27
|
+
};
|
|
28
|
+
const handleConnect = async () => {
|
|
38
29
|
try {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
30
|
+
setIsConnected(true);
|
|
31
|
+
setIsConnecting(false);
|
|
32
|
+
const providerInfo = sdkInstance.getCurrentProviderInfo();
|
|
33
|
+
setCurrentProviderType(providerInfo?.type || null);
|
|
34
|
+
const addrs = await sdkInstance.getAddresses();
|
|
35
|
+
setAddresses(addrs);
|
|
36
|
+
setWalletId(sdkInstance.getWalletId());
|
|
37
|
+
} catch (err) {
|
|
38
|
+
console.error("Error connecting:", err);
|
|
39
|
+
try {
|
|
40
|
+
await sdkInstance.disconnect();
|
|
41
|
+
} catch (err2) {
|
|
42
|
+
console.error("Error disconnecting:", err2);
|
|
43
|
+
}
|
|
45
44
|
}
|
|
46
|
-
}
|
|
47
|
-
|
|
45
|
+
};
|
|
46
|
+
const handleConnectError = (errorData) => {
|
|
47
|
+
setIsConnecting(false);
|
|
48
|
+
setIsConnected(false);
|
|
49
|
+
setConnectError(new Error(errorData.error || "Connection failed"));
|
|
50
|
+
};
|
|
51
|
+
const handleDisconnect = () => {
|
|
52
|
+
setIsConnected(false);
|
|
53
|
+
setIsConnecting(false);
|
|
54
|
+
setConnectError(null);
|
|
55
|
+
setAddresses([]);
|
|
56
|
+
setWalletId(null);
|
|
57
|
+
};
|
|
58
|
+
sdkInstance.on("connect_start", handleConnectStart);
|
|
59
|
+
sdkInstance.on("connect", handleConnect);
|
|
60
|
+
sdkInstance.on("connect_error", handleConnectError);
|
|
61
|
+
sdkInstance.on("disconnect", handleDisconnect);
|
|
62
|
+
setSdk(sdkInstance);
|
|
63
|
+
return () => {
|
|
64
|
+
sdkInstance.off("connect_start", handleConnectStart);
|
|
65
|
+
sdkInstance.off("connect", handleConnect);
|
|
66
|
+
sdkInstance.off("connect_error", handleConnectError);
|
|
67
|
+
sdkInstance.off("disconnect", handleDisconnect);
|
|
68
|
+
};
|
|
69
|
+
}, [memoizedConfig]);
|
|
48
70
|
useEffect(() => {
|
|
71
|
+
if (!sdk || !debugConfig)
|
|
72
|
+
return;
|
|
73
|
+
sdk.configureDebug(debugConfig);
|
|
74
|
+
}, [sdk, debugConfig]);
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
if (!sdk)
|
|
77
|
+
return;
|
|
49
78
|
const initialize = async () => {
|
|
50
79
|
try {
|
|
51
80
|
const available = await sdk.waitForPhantomExtension(1e3);
|
|
@@ -54,28 +83,31 @@ function PhantomProvider({ children, config }) {
|
|
|
54
83
|
console.error("Error checking Phantom extension:", err);
|
|
55
84
|
setIsPhantomAvailable(false);
|
|
56
85
|
}
|
|
57
|
-
|
|
86
|
+
if (config.autoConnect !== false) {
|
|
87
|
+
sdk.autoConnect().catch(() => {
|
|
88
|
+
});
|
|
89
|
+
}
|
|
58
90
|
};
|
|
59
91
|
initialize();
|
|
60
|
-
}, [sdk,
|
|
92
|
+
}, [sdk, config.autoConnect]);
|
|
61
93
|
const value = useMemo(
|
|
62
94
|
() => ({
|
|
63
95
|
sdk,
|
|
64
96
|
isConnected,
|
|
97
|
+
isConnecting,
|
|
98
|
+
connectError,
|
|
65
99
|
addresses,
|
|
66
|
-
updateConnectionState,
|
|
67
100
|
walletId,
|
|
68
|
-
error,
|
|
69
101
|
currentProviderType,
|
|
70
102
|
isPhantomAvailable
|
|
71
103
|
}),
|
|
72
104
|
[
|
|
73
105
|
sdk,
|
|
74
106
|
isConnected,
|
|
107
|
+
isConnecting,
|
|
108
|
+
connectError,
|
|
75
109
|
addresses,
|
|
76
|
-
updateConnectionState,
|
|
77
110
|
walletId,
|
|
78
|
-
error,
|
|
79
111
|
currentProviderType,
|
|
80
112
|
isPhantomAvailable
|
|
81
113
|
]
|
|
@@ -91,48 +123,40 @@ function usePhantom() {
|
|
|
91
123
|
}
|
|
92
124
|
|
|
93
125
|
// src/hooks/useConnect.ts
|
|
94
|
-
import { useCallback
|
|
126
|
+
import { useCallback } from "react";
|
|
95
127
|
function useConnect() {
|
|
96
|
-
const { sdk,
|
|
97
|
-
const
|
|
98
|
-
const [error, setError] = useState2(null);
|
|
99
|
-
const connect = useCallback2(
|
|
128
|
+
const { sdk, isConnecting, connectError, currentProviderType, isPhantomAvailable } = usePhantom();
|
|
129
|
+
const connect = useCallback(
|
|
100
130
|
async (options) => {
|
|
101
131
|
if (!sdk) {
|
|
102
132
|
throw new Error("SDK not initialized");
|
|
103
133
|
}
|
|
104
|
-
setIsConnecting(true);
|
|
105
|
-
setError(null);
|
|
106
134
|
try {
|
|
107
135
|
const result = await sdk.connect(options);
|
|
108
|
-
await updateConnectionState();
|
|
109
136
|
return result;
|
|
110
137
|
} catch (err) {
|
|
111
138
|
console.error("Error connecting to Phantom:", err);
|
|
112
|
-
setError(err);
|
|
113
139
|
throw err;
|
|
114
|
-
} finally {
|
|
115
|
-
setIsConnecting(false);
|
|
116
140
|
}
|
|
117
141
|
},
|
|
118
|
-
[sdk
|
|
142
|
+
[sdk]
|
|
119
143
|
);
|
|
120
144
|
return {
|
|
121
145
|
connect,
|
|
122
146
|
isConnecting,
|
|
123
|
-
error,
|
|
147
|
+
error: connectError,
|
|
124
148
|
currentProviderType,
|
|
125
149
|
isPhantomAvailable
|
|
126
150
|
};
|
|
127
151
|
}
|
|
128
152
|
|
|
129
153
|
// src/hooks/useDisconnect.ts
|
|
130
|
-
import { useCallback as
|
|
154
|
+
import { useCallback as useCallback2, useState as useState2 } from "react";
|
|
131
155
|
function useDisconnect() {
|
|
132
|
-
const { sdk
|
|
133
|
-
const [isDisconnecting, setIsDisconnecting] =
|
|
134
|
-
const [error, setError] =
|
|
135
|
-
const disconnect =
|
|
156
|
+
const { sdk } = usePhantom();
|
|
157
|
+
const [isDisconnecting, setIsDisconnecting] = useState2(false);
|
|
158
|
+
const [error, setError] = useState2(null);
|
|
159
|
+
const disconnect = useCallback2(async () => {
|
|
136
160
|
if (!sdk) {
|
|
137
161
|
throw new Error("SDK not initialized");
|
|
138
162
|
}
|
|
@@ -140,14 +164,13 @@ function useDisconnect() {
|
|
|
140
164
|
setError(null);
|
|
141
165
|
try {
|
|
142
166
|
await sdk.disconnect();
|
|
143
|
-
await updateConnectionState();
|
|
144
167
|
} catch (err) {
|
|
145
168
|
setError(err);
|
|
146
169
|
throw err;
|
|
147
170
|
} finally {
|
|
148
171
|
setIsDisconnecting(false);
|
|
149
172
|
}
|
|
150
|
-
}, [sdk
|
|
173
|
+
}, [sdk]);
|
|
151
174
|
return {
|
|
152
175
|
disconnect,
|
|
153
176
|
isDisconnecting,
|
|
@@ -156,17 +179,17 @@ function useDisconnect() {
|
|
|
156
179
|
}
|
|
157
180
|
|
|
158
181
|
// src/hooks/useSignMessage.ts
|
|
159
|
-
import { useCallback as
|
|
182
|
+
import { useCallback as useCallback3, useState as useState3 } from "react";
|
|
160
183
|
function useSignMessage() {
|
|
161
|
-
const { sdk
|
|
162
|
-
const [isSigning, setIsSigning] =
|
|
163
|
-
const [error, setError] =
|
|
164
|
-
const signMessage =
|
|
184
|
+
const { sdk } = usePhantom();
|
|
185
|
+
const [isSigning, setIsSigning] = useState3(false);
|
|
186
|
+
const [error, setError] = useState3(null);
|
|
187
|
+
const signMessage = useCallback3(
|
|
165
188
|
async (params) => {
|
|
166
189
|
if (!sdk) {
|
|
167
190
|
throw new Error("SDK not initialized");
|
|
168
191
|
}
|
|
169
|
-
if (!isConnected) {
|
|
192
|
+
if (!sdk.isConnected()) {
|
|
170
193
|
throw new Error("Wallet not connected");
|
|
171
194
|
}
|
|
172
195
|
setIsSigning(true);
|
|
@@ -181,7 +204,7 @@ function useSignMessage() {
|
|
|
181
204
|
setIsSigning(false);
|
|
182
205
|
}
|
|
183
206
|
},
|
|
184
|
-
[sdk
|
|
207
|
+
[sdk]
|
|
185
208
|
);
|
|
186
209
|
return {
|
|
187
210
|
signMessage,
|
|
@@ -191,17 +214,17 @@ function useSignMessage() {
|
|
|
191
214
|
}
|
|
192
215
|
|
|
193
216
|
// src/hooks/useSignAndSendTransaction.ts
|
|
194
|
-
import { useCallback as
|
|
217
|
+
import { useCallback as useCallback4, useState as useState4 } from "react";
|
|
195
218
|
function useSignAndSendTransaction() {
|
|
196
|
-
const { sdk
|
|
197
|
-
const [isSigning, setIsSigning] =
|
|
198
|
-
const [error, setError] =
|
|
199
|
-
const signAndSendTransaction =
|
|
219
|
+
const { sdk } = usePhantom();
|
|
220
|
+
const [isSigning, setIsSigning] = useState4(false);
|
|
221
|
+
const [error, setError] = useState4(null);
|
|
222
|
+
const signAndSendTransaction = useCallback4(
|
|
200
223
|
async (params) => {
|
|
201
224
|
if (!sdk) {
|
|
202
225
|
throw new Error("SDK not initialized");
|
|
203
226
|
}
|
|
204
|
-
if (!isConnected) {
|
|
227
|
+
if (!sdk.isConnected()) {
|
|
205
228
|
throw new Error("Wallet not connected");
|
|
206
229
|
}
|
|
207
230
|
setIsSigning(true);
|
|
@@ -216,7 +239,7 @@ function useSignAndSendTransaction() {
|
|
|
216
239
|
setIsSigning(false);
|
|
217
240
|
}
|
|
218
241
|
},
|
|
219
|
-
[sdk
|
|
242
|
+
[sdk]
|
|
220
243
|
);
|
|
221
244
|
return {
|
|
222
245
|
signAndSendTransaction,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phantom/react-sdk",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.6",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"module": "dist/index.mjs",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"prettier": "prettier --write \"src/**/*.{ts,tsx}\""
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@phantom/browser-sdk": "^0.3.
|
|
29
|
+
"@phantom/browser-sdk": "^0.3.6"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@testing-library/dom": "^10.4.0",
|