@phantom/react-sdk 0.3.4 → 0.3.5

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
@@ -652,6 +652,7 @@ 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)
655
656
 
656
657
  // Debug options
657
658
  debug?: {
package/dist/index.d.ts CHANGED
@@ -14,12 +14,12 @@ interface ConnectOptions {
14
14
  interface PhantomContextValue {
15
15
  sdk: BrowserSDK;
16
16
  isConnected: boolean;
17
+ isConnecting: boolean;
18
+ connectError: Error | null;
17
19
  addresses: WalletAddress[];
18
20
  walletId: string | null;
19
- error: Error | null;
20
21
  currentProviderType: "injected" | "embedded" | null;
21
22
  isPhantomAvailable: boolean;
22
- updateConnectionState: () => Promise<void>;
23
23
  }
24
24
  interface PhantomProviderProps {
25
25
  children: ReactNode;
package/dist/index.js CHANGED
@@ -51,47 +51,62 @@ 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
53
  function PhantomProvider({ children, config }) {
54
- const sdk = (0, import_react.useMemo)(
55
- () => new import_browser_sdk.BrowserSDK({
54
+ const memoizedConfig = (0, import_react.useMemo)(() => {
55
+ return {
56
56
  ...config,
57
57
  // Use providerType if provided, default to embedded
58
58
  providerType: config.providerType || "embedded"
59
- }),
60
- [config]
61
- );
59
+ };
60
+ }, [config]);
61
+ const sdk = (0, import_react.useMemo)(() => {
62
+ const sdkInstance = new import_browser_sdk.BrowserSDK(memoizedConfig);
63
+ const handleConnectStart = () => {
64
+ setIsConnecting(true);
65
+ setConnectError(null);
66
+ };
67
+ const handleConnect = async () => {
68
+ try {
69
+ setIsConnected(true);
70
+ setIsConnecting(false);
71
+ const providerInfo = sdkInstance.getCurrentProviderInfo();
72
+ setCurrentProviderType(providerInfo?.type || null);
73
+ const addrs = await sdkInstance.getAddresses();
74
+ setAddresses(addrs);
75
+ setWalletId(sdkInstance.getWalletId());
76
+ } catch (err) {
77
+ console.error("Error connecting:", err);
78
+ try {
79
+ await sdkInstance.disconnect();
80
+ } catch (err2) {
81
+ console.error("Error disconnecting:", err2);
82
+ }
83
+ }
84
+ };
85
+ const handleConnectError = (errorData) => {
86
+ setIsConnecting(false);
87
+ setIsConnected(false);
88
+ setConnectError(new Error(errorData.error || "Connection failed"));
89
+ };
90
+ const handleDisconnect = () => {
91
+ setIsConnected(false);
92
+ setIsConnecting(false);
93
+ setConnectError(null);
94
+ setAddresses([]);
95
+ setWalletId(null);
96
+ };
97
+ sdkInstance.on("connect_start", handleConnectStart);
98
+ sdkInstance.on("connect", handleConnect);
99
+ sdkInstance.on("connect_error", handleConnectError);
100
+ sdkInstance.on("disconnect", handleDisconnect);
101
+ return sdkInstance;
102
+ }, [memoizedConfig]);
62
103
  const [isConnected, setIsConnected] = (0, import_react.useState)(false);
104
+ const [isConnecting, setIsConnecting] = (0, import_react.useState)(false);
105
+ const [connectError, setConnectError] = (0, import_react.useState)(null);
63
106
  const [addresses, setAddresses] = (0, import_react.useState)([]);
64
107
  const [walletId, setWalletId] = (0, import_react.useState)(null);
65
- const [error, setError] = (0, import_react.useState)(null);
66
108
  const [currentProviderType, setCurrentProviderType] = (0, import_react.useState)(null);
67
109
  const [isPhantomAvailable, setIsPhantomAvailable] = (0, import_react.useState)(false);
68
- const updateConnectionState = (0, import_react.useCallback)(async () => {
69
- try {
70
- const connected = sdk.isConnected();
71
- setIsConnected(connected);
72
- const providerInfo = sdk.getCurrentProviderInfo();
73
- setCurrentProviderType(providerInfo?.type || null);
74
- if (connected) {
75
- const addrs = await sdk.getAddresses();
76
- setAddresses(addrs);
77
- setWalletId(sdk.getWalletId());
78
- } else {
79
- setAddresses([]);
80
- setWalletId(null);
81
- }
82
- } catch (err) {
83
- console.error("Error updating connection state:", err);
84
- setError(err);
85
- try {
86
- await sdk.disconnect();
87
- setIsConnected(false);
88
- setAddresses([]);
89
- setWalletId(null);
90
- } catch (err2) {
91
- console.error("Error disconnecting:", err2);
92
- }
93
- }
94
- }, [sdk]);
95
110
  (0, import_react.useEffect)(() => {
96
111
  const initialize = async () => {
97
112
  try {
@@ -101,28 +116,31 @@ function PhantomProvider({ children, config }) {
101
116
  console.error("Error checking Phantom extension:", err);
102
117
  setIsPhantomAvailable(false);
103
118
  }
104
- await updateConnectionState();
119
+ if (config.autoConnect !== false) {
120
+ sdk.autoConnect().catch(() => {
121
+ });
122
+ }
105
123
  };
106
124
  initialize();
107
- }, [sdk, updateConnectionState]);
125
+ }, [sdk, config.autoConnect]);
108
126
  const value = (0, import_react.useMemo)(
109
127
  () => ({
110
128
  sdk,
111
129
  isConnected,
130
+ isConnecting,
131
+ connectError,
112
132
  addresses,
113
- updateConnectionState,
114
133
  walletId,
115
- error,
116
134
  currentProviderType,
117
135
  isPhantomAvailable
118
136
  }),
119
137
  [
120
138
  sdk,
121
139
  isConnected,
140
+ isConnecting,
141
+ connectError,
122
142
  addresses,
123
- updateConnectionState,
124
143
  walletId,
125
- error,
126
144
  currentProviderType,
127
145
  isPhantomAvailable
128
146
  ]
@@ -140,34 +158,26 @@ function usePhantom() {
140
158
  // src/hooks/useConnect.ts
141
159
  var import_react2 = require("react");
142
160
  function useConnect() {
143
- const { sdk, updateConnectionState, currentProviderType, isPhantomAvailable } = usePhantom();
144
- const [isConnecting, setIsConnecting] = (0, import_react2.useState)(false);
145
- const [error, setError] = (0, import_react2.useState)(null);
161
+ const { sdk, isConnecting, connectError, currentProviderType, isPhantomAvailable } = usePhantom();
146
162
  const connect = (0, import_react2.useCallback)(
147
163
  async (options) => {
148
164
  if (!sdk) {
149
165
  throw new Error("SDK not initialized");
150
166
  }
151
- setIsConnecting(true);
152
- setError(null);
153
167
  try {
154
168
  const result = await sdk.connect(options);
155
- await updateConnectionState();
156
169
  return result;
157
170
  } catch (err) {
158
171
  console.error("Error connecting to Phantom:", err);
159
- setError(err);
160
172
  throw err;
161
- } finally {
162
- setIsConnecting(false);
163
173
  }
164
174
  },
165
- [sdk, updateConnectionState]
175
+ [sdk]
166
176
  );
167
177
  return {
168
178
  connect,
169
179
  isConnecting,
170
- error,
180
+ error: connectError,
171
181
  currentProviderType,
172
182
  isPhantomAvailable
173
183
  };
@@ -176,7 +186,7 @@ function useConnect() {
176
186
  // src/hooks/useDisconnect.ts
177
187
  var import_react3 = require("react");
178
188
  function useDisconnect() {
179
- const { sdk, updateConnectionState } = usePhantom();
189
+ const { sdk } = usePhantom();
180
190
  const [isDisconnecting, setIsDisconnecting] = (0, import_react3.useState)(false);
181
191
  const [error, setError] = (0, import_react3.useState)(null);
182
192
  const disconnect = (0, import_react3.useCallback)(async () => {
@@ -187,14 +197,13 @@ function useDisconnect() {
187
197
  setError(null);
188
198
  try {
189
199
  await sdk.disconnect();
190
- await updateConnectionState();
191
200
  } catch (err) {
192
201
  setError(err);
193
202
  throw err;
194
203
  } finally {
195
204
  setIsDisconnecting(false);
196
205
  }
197
- }, [sdk, updateConnectionState]);
206
+ }, [sdk]);
198
207
  return {
199
208
  disconnect,
200
209
  isDisconnecting,
@@ -205,7 +214,7 @@ function useDisconnect() {
205
214
  // src/hooks/useSignMessage.ts
206
215
  var import_react4 = require("react");
207
216
  function useSignMessage() {
208
- const { sdk, isConnected } = usePhantom();
217
+ const { sdk } = usePhantom();
209
218
  const [isSigning, setIsSigning] = (0, import_react4.useState)(false);
210
219
  const [error, setError] = (0, import_react4.useState)(null);
211
220
  const signMessage = (0, import_react4.useCallback)(
@@ -213,7 +222,7 @@ function useSignMessage() {
213
222
  if (!sdk) {
214
223
  throw new Error("SDK not initialized");
215
224
  }
216
- if (!isConnected) {
225
+ if (!sdk.isConnected()) {
217
226
  throw new Error("Wallet not connected");
218
227
  }
219
228
  setIsSigning(true);
@@ -228,7 +237,7 @@ function useSignMessage() {
228
237
  setIsSigning(false);
229
238
  }
230
239
  },
231
- [sdk, isConnected]
240
+ [sdk]
232
241
  );
233
242
  return {
234
243
  signMessage,
@@ -240,7 +249,7 @@ function useSignMessage() {
240
249
  // src/hooks/useSignAndSendTransaction.ts
241
250
  var import_react5 = require("react");
242
251
  function useSignAndSendTransaction() {
243
- const { sdk, isConnected } = usePhantom();
252
+ const { sdk } = usePhantom();
244
253
  const [isSigning, setIsSigning] = (0, import_react5.useState)(false);
245
254
  const [error, setError] = (0, import_react5.useState)(null);
246
255
  const signAndSendTransaction = (0, import_react5.useCallback)(
@@ -248,7 +257,7 @@ function useSignAndSendTransaction() {
248
257
  if (!sdk) {
249
258
  throw new Error("SDK not initialized");
250
259
  }
251
- if (!isConnected) {
260
+ if (!sdk.isConnected()) {
252
261
  throw new Error("Wallet not connected");
253
262
  }
254
263
  setIsSigning(true);
@@ -263,7 +272,7 @@ function useSignAndSendTransaction() {
263
272
  setIsSigning(false);
264
273
  }
265
274
  },
266
- [sdk, isConnected]
275
+ [sdk]
267
276
  );
268
277
  return {
269
278
  signAndSendTransaction,
package/dist/index.mjs CHANGED
@@ -1,50 +1,65 @@
1
1
  // src/PhantomProvider.tsx
2
- import { createContext, useContext, useState, useEffect, useCallback, useMemo } from "react";
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
6
  function PhantomProvider({ children, config }) {
7
- const sdk = useMemo(
8
- () => new BrowserSDK({
7
+ const memoizedConfig = useMemo(() => {
8
+ return {
9
9
  ...config,
10
10
  // Use providerType if provided, default to embedded
11
11
  providerType: config.providerType || "embedded"
12
- }),
13
- [config]
14
- );
12
+ };
13
+ }, [config]);
14
+ const sdk = useMemo(() => {
15
+ const sdkInstance = new BrowserSDK(memoizedConfig);
16
+ const handleConnectStart = () => {
17
+ setIsConnecting(true);
18
+ setConnectError(null);
19
+ };
20
+ const handleConnect = async () => {
21
+ try {
22
+ setIsConnected(true);
23
+ setIsConnecting(false);
24
+ const providerInfo = sdkInstance.getCurrentProviderInfo();
25
+ setCurrentProviderType(providerInfo?.type || null);
26
+ const addrs = await sdkInstance.getAddresses();
27
+ setAddresses(addrs);
28
+ setWalletId(sdkInstance.getWalletId());
29
+ } catch (err) {
30
+ console.error("Error connecting:", err);
31
+ try {
32
+ await sdkInstance.disconnect();
33
+ } catch (err2) {
34
+ console.error("Error disconnecting:", err2);
35
+ }
36
+ }
37
+ };
38
+ const handleConnectError = (errorData) => {
39
+ setIsConnecting(false);
40
+ setIsConnected(false);
41
+ setConnectError(new Error(errorData.error || "Connection failed"));
42
+ };
43
+ const handleDisconnect = () => {
44
+ setIsConnected(false);
45
+ setIsConnecting(false);
46
+ setConnectError(null);
47
+ setAddresses([]);
48
+ setWalletId(null);
49
+ };
50
+ sdkInstance.on("connect_start", handleConnectStart);
51
+ sdkInstance.on("connect", handleConnect);
52
+ sdkInstance.on("connect_error", handleConnectError);
53
+ sdkInstance.on("disconnect", handleDisconnect);
54
+ return sdkInstance;
55
+ }, [memoizedConfig]);
15
56
  const [isConnected, setIsConnected] = useState(false);
57
+ const [isConnecting, setIsConnecting] = useState(false);
58
+ const [connectError, setConnectError] = useState(null);
16
59
  const [addresses, setAddresses] = useState([]);
17
60
  const [walletId, setWalletId] = useState(null);
18
- const [error, setError] = useState(null);
19
61
  const [currentProviderType, setCurrentProviderType] = useState(null);
20
62
  const [isPhantomAvailable, setIsPhantomAvailable] = useState(false);
21
- const updateConnectionState = useCallback(async () => {
22
- try {
23
- const connected = sdk.isConnected();
24
- setIsConnected(connected);
25
- const providerInfo = sdk.getCurrentProviderInfo();
26
- setCurrentProviderType(providerInfo?.type || null);
27
- if (connected) {
28
- const addrs = await sdk.getAddresses();
29
- setAddresses(addrs);
30
- setWalletId(sdk.getWalletId());
31
- } else {
32
- setAddresses([]);
33
- setWalletId(null);
34
- }
35
- } catch (err) {
36
- console.error("Error updating connection state:", err);
37
- setError(err);
38
- try {
39
- await sdk.disconnect();
40
- setIsConnected(false);
41
- setAddresses([]);
42
- setWalletId(null);
43
- } catch (err2) {
44
- console.error("Error disconnecting:", err2);
45
- }
46
- }
47
- }, [sdk]);
48
63
  useEffect(() => {
49
64
  const initialize = async () => {
50
65
  try {
@@ -54,28 +69,31 @@ function PhantomProvider({ children, config }) {
54
69
  console.error("Error checking Phantom extension:", err);
55
70
  setIsPhantomAvailable(false);
56
71
  }
57
- await updateConnectionState();
72
+ if (config.autoConnect !== false) {
73
+ sdk.autoConnect().catch(() => {
74
+ });
75
+ }
58
76
  };
59
77
  initialize();
60
- }, [sdk, updateConnectionState]);
78
+ }, [sdk, config.autoConnect]);
61
79
  const value = useMemo(
62
80
  () => ({
63
81
  sdk,
64
82
  isConnected,
83
+ isConnecting,
84
+ connectError,
65
85
  addresses,
66
- updateConnectionState,
67
86
  walletId,
68
- error,
69
87
  currentProviderType,
70
88
  isPhantomAvailable
71
89
  }),
72
90
  [
73
91
  sdk,
74
92
  isConnected,
93
+ isConnecting,
94
+ connectError,
75
95
  addresses,
76
- updateConnectionState,
77
96
  walletId,
78
- error,
79
97
  currentProviderType,
80
98
  isPhantomAvailable
81
99
  ]
@@ -91,48 +109,40 @@ function usePhantom() {
91
109
  }
92
110
 
93
111
  // src/hooks/useConnect.ts
94
- import { useCallback as useCallback2, useState as useState2 } from "react";
112
+ import { useCallback } from "react";
95
113
  function useConnect() {
96
- const { sdk, updateConnectionState, currentProviderType, isPhantomAvailable } = usePhantom();
97
- const [isConnecting, setIsConnecting] = useState2(false);
98
- const [error, setError] = useState2(null);
99
- const connect = useCallback2(
114
+ const { sdk, isConnecting, connectError, currentProviderType, isPhantomAvailable } = usePhantom();
115
+ const connect = useCallback(
100
116
  async (options) => {
101
117
  if (!sdk) {
102
118
  throw new Error("SDK not initialized");
103
119
  }
104
- setIsConnecting(true);
105
- setError(null);
106
120
  try {
107
121
  const result = await sdk.connect(options);
108
- await updateConnectionState();
109
122
  return result;
110
123
  } catch (err) {
111
124
  console.error("Error connecting to Phantom:", err);
112
- setError(err);
113
125
  throw err;
114
- } finally {
115
- setIsConnecting(false);
116
126
  }
117
127
  },
118
- [sdk, updateConnectionState]
128
+ [sdk]
119
129
  );
120
130
  return {
121
131
  connect,
122
132
  isConnecting,
123
- error,
133
+ error: connectError,
124
134
  currentProviderType,
125
135
  isPhantomAvailable
126
136
  };
127
137
  }
128
138
 
129
139
  // src/hooks/useDisconnect.ts
130
- import { useCallback as useCallback3, useState as useState3 } from "react";
140
+ import { useCallback as useCallback2, useState as useState2 } from "react";
131
141
  function useDisconnect() {
132
- const { sdk, updateConnectionState } = usePhantom();
133
- const [isDisconnecting, setIsDisconnecting] = useState3(false);
134
- const [error, setError] = useState3(null);
135
- const disconnect = useCallback3(async () => {
142
+ const { sdk } = usePhantom();
143
+ const [isDisconnecting, setIsDisconnecting] = useState2(false);
144
+ const [error, setError] = useState2(null);
145
+ const disconnect = useCallback2(async () => {
136
146
  if (!sdk) {
137
147
  throw new Error("SDK not initialized");
138
148
  }
@@ -140,14 +150,13 @@ function useDisconnect() {
140
150
  setError(null);
141
151
  try {
142
152
  await sdk.disconnect();
143
- await updateConnectionState();
144
153
  } catch (err) {
145
154
  setError(err);
146
155
  throw err;
147
156
  } finally {
148
157
  setIsDisconnecting(false);
149
158
  }
150
- }, [sdk, updateConnectionState]);
159
+ }, [sdk]);
151
160
  return {
152
161
  disconnect,
153
162
  isDisconnecting,
@@ -156,17 +165,17 @@ function useDisconnect() {
156
165
  }
157
166
 
158
167
  // src/hooks/useSignMessage.ts
159
- import { useCallback as useCallback4, useState as useState4 } from "react";
168
+ import { useCallback as useCallback3, useState as useState3 } from "react";
160
169
  function useSignMessage() {
161
- const { sdk, isConnected } = usePhantom();
162
- const [isSigning, setIsSigning] = useState4(false);
163
- const [error, setError] = useState4(null);
164
- const signMessage = useCallback4(
170
+ const { sdk } = usePhantom();
171
+ const [isSigning, setIsSigning] = useState3(false);
172
+ const [error, setError] = useState3(null);
173
+ const signMessage = useCallback3(
165
174
  async (params) => {
166
175
  if (!sdk) {
167
176
  throw new Error("SDK not initialized");
168
177
  }
169
- if (!isConnected) {
178
+ if (!sdk.isConnected()) {
170
179
  throw new Error("Wallet not connected");
171
180
  }
172
181
  setIsSigning(true);
@@ -181,7 +190,7 @@ function useSignMessage() {
181
190
  setIsSigning(false);
182
191
  }
183
192
  },
184
- [sdk, isConnected]
193
+ [sdk]
185
194
  );
186
195
  return {
187
196
  signMessage,
@@ -191,17 +200,17 @@ function useSignMessage() {
191
200
  }
192
201
 
193
202
  // src/hooks/useSignAndSendTransaction.ts
194
- import { useCallback as useCallback5, useState as useState5 } from "react";
203
+ import { useCallback as useCallback4, useState as useState4 } from "react";
195
204
  function useSignAndSendTransaction() {
196
- const { sdk, isConnected } = usePhantom();
197
- const [isSigning, setIsSigning] = useState5(false);
198
- const [error, setError] = useState5(null);
199
- const signAndSendTransaction = useCallback5(
205
+ const { sdk } = usePhantom();
206
+ const [isSigning, setIsSigning] = useState4(false);
207
+ const [error, setError] = useState4(null);
208
+ const signAndSendTransaction = useCallback4(
200
209
  async (params) => {
201
210
  if (!sdk) {
202
211
  throw new Error("SDK not initialized");
203
212
  }
204
- if (!isConnected) {
213
+ if (!sdk.isConnected()) {
205
214
  throw new Error("Wallet not connected");
206
215
  }
207
216
  setIsSigning(true);
@@ -216,7 +225,7 @@ function useSignAndSendTransaction() {
216
225
  setIsSigning(false);
217
226
  }
218
227
  },
219
- [sdk, isConnected]
228
+ [sdk]
220
229
  );
221
230
  return {
222
231
  signAndSendTransaction,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phantom/react-sdk",
3
- "version": "0.3.4",
3
+ "version": "0.3.5",
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.4"
29
+ "@phantom/browser-sdk": "^0.3.5"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@testing-library/dom": "^10.4.0",