@phantom/react-sdk 0.3.3 → 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,49 +51,64 @@ 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
- const checkPhantomExtension = async () => {
111
+ const initialize = async () => {
97
112
  try {
98
113
  const available = await sdk.waitForPhantomExtension(1e3);
99
114
  setIsPhantomAvailable(available);
@@ -101,23 +116,35 @@ function PhantomProvider({ children, config }) {
101
116
  console.error("Error checking Phantom extension:", err);
102
117
  setIsPhantomAvailable(false);
103
118
  }
119
+ if (config.autoConnect !== false) {
120
+ sdk.autoConnect().catch(() => {
121
+ });
122
+ }
104
123
  };
105
- checkPhantomExtension();
106
- updateConnectionState();
107
- }, [sdk, updateConnectionState]);
108
- (0, import_react.useEffect)(() => {
109
- updateConnectionState();
110
- }, [updateConnectionState]);
111
- const value = {
112
- sdk,
113
- isConnected,
114
- addresses,
115
- updateConnectionState,
116
- walletId,
117
- error,
118
- currentProviderType,
119
- isPhantomAvailable
120
- };
124
+ initialize();
125
+ }, [sdk, config.autoConnect]);
126
+ const value = (0, import_react.useMemo)(
127
+ () => ({
128
+ sdk,
129
+ isConnected,
130
+ isConnecting,
131
+ connectError,
132
+ addresses,
133
+ walletId,
134
+ currentProviderType,
135
+ isPhantomAvailable
136
+ }),
137
+ [
138
+ sdk,
139
+ isConnected,
140
+ isConnecting,
141
+ connectError,
142
+ addresses,
143
+ walletId,
144
+ currentProviderType,
145
+ isPhantomAvailable
146
+ ]
147
+ );
121
148
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PhantomContext.Provider, { value, children });
122
149
  }
123
150
  function usePhantom() {
@@ -131,43 +158,35 @@ function usePhantom() {
131
158
  // src/hooks/useConnect.ts
132
159
  var import_react2 = require("react");
133
160
  function useConnect() {
134
- const context = usePhantom();
135
- const [isConnecting, setIsConnecting] = (0, import_react2.useState)(false);
136
- const [error, setError] = (0, import_react2.useState)(null);
161
+ const { sdk, isConnecting, connectError, currentProviderType, isPhantomAvailable } = usePhantom();
137
162
  const connect = (0, import_react2.useCallback)(
138
163
  async (options) => {
139
- if (!context.sdk) {
164
+ if (!sdk) {
140
165
  throw new Error("SDK not initialized");
141
166
  }
142
- setIsConnecting(true);
143
- setError(null);
144
167
  try {
145
- const result = await context.sdk.connect(options);
146
- await context.updateConnectionState();
168
+ const result = await sdk.connect(options);
147
169
  return result;
148
170
  } catch (err) {
149
171
  console.error("Error connecting to Phantom:", err);
150
- setError(err);
151
172
  throw err;
152
- } finally {
153
- setIsConnecting(false);
154
173
  }
155
174
  },
156
- [context]
175
+ [sdk]
157
176
  );
158
177
  return {
159
178
  connect,
160
179
  isConnecting,
161
- error,
162
- currentProviderType: context.currentProviderType,
163
- isPhantomAvailable: context.isPhantomAvailable
180
+ error: connectError,
181
+ currentProviderType,
182
+ isPhantomAvailable
164
183
  };
165
184
  }
166
185
 
167
186
  // src/hooks/useDisconnect.ts
168
187
  var import_react3 = require("react");
169
188
  function useDisconnect() {
170
- const { sdk, updateConnectionState } = usePhantom();
189
+ const { sdk } = usePhantom();
171
190
  const [isDisconnecting, setIsDisconnecting] = (0, import_react3.useState)(false);
172
191
  const [error, setError] = (0, import_react3.useState)(null);
173
192
  const disconnect = (0, import_react3.useCallback)(async () => {
@@ -178,14 +197,13 @@ function useDisconnect() {
178
197
  setError(null);
179
198
  try {
180
199
  await sdk.disconnect();
181
- await updateConnectionState();
182
200
  } catch (err) {
183
201
  setError(err);
184
202
  throw err;
185
203
  } finally {
186
204
  setIsDisconnecting(false);
187
205
  }
188
- }, [sdk, updateConnectionState]);
206
+ }, [sdk]);
189
207
  return {
190
208
  disconnect,
191
209
  isDisconnecting,
@@ -196,7 +214,7 @@ function useDisconnect() {
196
214
  // src/hooks/useSignMessage.ts
197
215
  var import_react4 = require("react");
198
216
  function useSignMessage() {
199
- const { sdk, isConnected } = usePhantom();
217
+ const { sdk } = usePhantom();
200
218
  const [isSigning, setIsSigning] = (0, import_react4.useState)(false);
201
219
  const [error, setError] = (0, import_react4.useState)(null);
202
220
  const signMessage = (0, import_react4.useCallback)(
@@ -204,7 +222,7 @@ function useSignMessage() {
204
222
  if (!sdk) {
205
223
  throw new Error("SDK not initialized");
206
224
  }
207
- if (!isConnected) {
225
+ if (!sdk.isConnected()) {
208
226
  throw new Error("Wallet not connected");
209
227
  }
210
228
  setIsSigning(true);
@@ -219,7 +237,7 @@ function useSignMessage() {
219
237
  setIsSigning(false);
220
238
  }
221
239
  },
222
- [sdk, isConnected]
240
+ [sdk]
223
241
  );
224
242
  return {
225
243
  signMessage,
@@ -231,7 +249,7 @@ function useSignMessage() {
231
249
  // src/hooks/useSignAndSendTransaction.ts
232
250
  var import_react5 = require("react");
233
251
  function useSignAndSendTransaction() {
234
- const { sdk, isConnected } = usePhantom();
252
+ const { sdk } = usePhantom();
235
253
  const [isSigning, setIsSigning] = (0, import_react5.useState)(false);
236
254
  const [error, setError] = (0, import_react5.useState)(null);
237
255
  const signAndSendTransaction = (0, import_react5.useCallback)(
@@ -239,7 +257,7 @@ function useSignAndSendTransaction() {
239
257
  if (!sdk) {
240
258
  throw new Error("SDK not initialized");
241
259
  }
242
- if (!isConnected) {
260
+ if (!sdk.isConnected()) {
243
261
  throw new Error("Wallet not connected");
244
262
  }
245
263
  setIsSigning(true);
@@ -254,7 +272,7 @@ function useSignAndSendTransaction() {
254
272
  setIsSigning(false);
255
273
  }
256
274
  },
257
- [sdk, isConnected]
275
+ [sdk]
258
276
  );
259
277
  return {
260
278
  signAndSendTransaction,
package/dist/index.mjs CHANGED
@@ -1,52 +1,67 @@
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
- const checkPhantomExtension = async () => {
64
+ const initialize = async () => {
50
65
  try {
51
66
  const available = await sdk.waitForPhantomExtension(1e3);
52
67
  setIsPhantomAvailable(available);
@@ -54,23 +69,35 @@ function PhantomProvider({ children, config }) {
54
69
  console.error("Error checking Phantom extension:", err);
55
70
  setIsPhantomAvailable(false);
56
71
  }
72
+ if (config.autoConnect !== false) {
73
+ sdk.autoConnect().catch(() => {
74
+ });
75
+ }
57
76
  };
58
- checkPhantomExtension();
59
- updateConnectionState();
60
- }, [sdk, updateConnectionState]);
61
- useEffect(() => {
62
- updateConnectionState();
63
- }, [updateConnectionState]);
64
- const value = {
65
- sdk,
66
- isConnected,
67
- addresses,
68
- updateConnectionState,
69
- walletId,
70
- error,
71
- currentProviderType,
72
- isPhantomAvailable
73
- };
77
+ initialize();
78
+ }, [sdk, config.autoConnect]);
79
+ const value = useMemo(
80
+ () => ({
81
+ sdk,
82
+ isConnected,
83
+ isConnecting,
84
+ connectError,
85
+ addresses,
86
+ walletId,
87
+ currentProviderType,
88
+ isPhantomAvailable
89
+ }),
90
+ [
91
+ sdk,
92
+ isConnected,
93
+ isConnecting,
94
+ connectError,
95
+ addresses,
96
+ walletId,
97
+ currentProviderType,
98
+ isPhantomAvailable
99
+ ]
100
+ );
74
101
  return /* @__PURE__ */ jsx(PhantomContext.Provider, { value, children });
75
102
  }
76
103
  function usePhantom() {
@@ -82,48 +109,40 @@ function usePhantom() {
82
109
  }
83
110
 
84
111
  // src/hooks/useConnect.ts
85
- import { useCallback as useCallback2, useState as useState2 } from "react";
112
+ import { useCallback } from "react";
86
113
  function useConnect() {
87
- const context = usePhantom();
88
- const [isConnecting, setIsConnecting] = useState2(false);
89
- const [error, setError] = useState2(null);
90
- const connect = useCallback2(
114
+ const { sdk, isConnecting, connectError, currentProviderType, isPhantomAvailable } = usePhantom();
115
+ const connect = useCallback(
91
116
  async (options) => {
92
- if (!context.sdk) {
117
+ if (!sdk) {
93
118
  throw new Error("SDK not initialized");
94
119
  }
95
- setIsConnecting(true);
96
- setError(null);
97
120
  try {
98
- const result = await context.sdk.connect(options);
99
- await context.updateConnectionState();
121
+ const result = await sdk.connect(options);
100
122
  return result;
101
123
  } catch (err) {
102
124
  console.error("Error connecting to Phantom:", err);
103
- setError(err);
104
125
  throw err;
105
- } finally {
106
- setIsConnecting(false);
107
126
  }
108
127
  },
109
- [context]
128
+ [sdk]
110
129
  );
111
130
  return {
112
131
  connect,
113
132
  isConnecting,
114
- error,
115
- currentProviderType: context.currentProviderType,
116
- isPhantomAvailable: context.isPhantomAvailable
133
+ error: connectError,
134
+ currentProviderType,
135
+ isPhantomAvailable
117
136
  };
118
137
  }
119
138
 
120
139
  // src/hooks/useDisconnect.ts
121
- import { useCallback as useCallback3, useState as useState3 } from "react";
140
+ import { useCallback as useCallback2, useState as useState2 } from "react";
122
141
  function useDisconnect() {
123
- const { sdk, updateConnectionState } = usePhantom();
124
- const [isDisconnecting, setIsDisconnecting] = useState3(false);
125
- const [error, setError] = useState3(null);
126
- 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 () => {
127
146
  if (!sdk) {
128
147
  throw new Error("SDK not initialized");
129
148
  }
@@ -131,14 +150,13 @@ function useDisconnect() {
131
150
  setError(null);
132
151
  try {
133
152
  await sdk.disconnect();
134
- await updateConnectionState();
135
153
  } catch (err) {
136
154
  setError(err);
137
155
  throw err;
138
156
  } finally {
139
157
  setIsDisconnecting(false);
140
158
  }
141
- }, [sdk, updateConnectionState]);
159
+ }, [sdk]);
142
160
  return {
143
161
  disconnect,
144
162
  isDisconnecting,
@@ -147,17 +165,17 @@ function useDisconnect() {
147
165
  }
148
166
 
149
167
  // src/hooks/useSignMessage.ts
150
- import { useCallback as useCallback4, useState as useState4 } from "react";
168
+ import { useCallback as useCallback3, useState as useState3 } from "react";
151
169
  function useSignMessage() {
152
- const { sdk, isConnected } = usePhantom();
153
- const [isSigning, setIsSigning] = useState4(false);
154
- const [error, setError] = useState4(null);
155
- const signMessage = useCallback4(
170
+ const { sdk } = usePhantom();
171
+ const [isSigning, setIsSigning] = useState3(false);
172
+ const [error, setError] = useState3(null);
173
+ const signMessage = useCallback3(
156
174
  async (params) => {
157
175
  if (!sdk) {
158
176
  throw new Error("SDK not initialized");
159
177
  }
160
- if (!isConnected) {
178
+ if (!sdk.isConnected()) {
161
179
  throw new Error("Wallet not connected");
162
180
  }
163
181
  setIsSigning(true);
@@ -172,7 +190,7 @@ function useSignMessage() {
172
190
  setIsSigning(false);
173
191
  }
174
192
  },
175
- [sdk, isConnected]
193
+ [sdk]
176
194
  );
177
195
  return {
178
196
  signMessage,
@@ -182,17 +200,17 @@ function useSignMessage() {
182
200
  }
183
201
 
184
202
  // src/hooks/useSignAndSendTransaction.ts
185
- import { useCallback as useCallback5, useState as useState5 } from "react";
203
+ import { useCallback as useCallback4, useState as useState4 } from "react";
186
204
  function useSignAndSendTransaction() {
187
- const { sdk, isConnected } = usePhantom();
188
- const [isSigning, setIsSigning] = useState5(false);
189
- const [error, setError] = useState5(null);
190
- const signAndSendTransaction = useCallback5(
205
+ const { sdk } = usePhantom();
206
+ const [isSigning, setIsSigning] = useState4(false);
207
+ const [error, setError] = useState4(null);
208
+ const signAndSendTransaction = useCallback4(
191
209
  async (params) => {
192
210
  if (!sdk) {
193
211
  throw new Error("SDK not initialized");
194
212
  }
195
- if (!isConnected) {
213
+ if (!sdk.isConnected()) {
196
214
  throw new Error("Wallet not connected");
197
215
  }
198
216
  setIsSigning(true);
@@ -207,7 +225,7 @@ function useSignAndSendTransaction() {
207
225
  setIsSigning(false);
208
226
  }
209
227
  },
210
- [sdk, isConnected]
228
+ [sdk]
211
229
  );
212
230
  return {
213
231
  signAndSendTransaction,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phantom/react-sdk",
3
- "version": "0.3.3",
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.3"
29
+ "@phantom/browser-sdk": "^0.3.5"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@testing-library/dom": "^10.4.0",