@phantom/react-sdk 0.3.9 → 1.0.0-beta.1

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/dist/index.mjs CHANGED
@@ -4,14 +4,6 @@ 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, debugConfig }) {
7
- const [isConnected, setIsConnected] = useState(false);
8
- const [isConnecting, setIsConnecting] = useState(false);
9
- const [connectError, setConnectError] = useState(null);
10
- const [addresses, setAddresses] = useState([]);
11
- const [walletId, setWalletId] = useState(null);
12
- const [currentProviderType, setCurrentProviderType] = useState(config.providerType || null);
13
- const [isPhantomAvailable, setIsPhantomAvailable] = useState(false);
14
- const [sdk, setSdk] = useState(null);
15
7
  const memoizedConfig = useMemo(() => {
16
8
  return {
17
9
  ...config,
@@ -19,6 +11,16 @@ function PhantomProvider({ children, config, debugConfig }) {
19
11
  providerType: config.providerType || "embedded"
20
12
  };
21
13
  }, [config]);
14
+ const [isConnected, setIsConnected] = useState(false);
15
+ const [isConnecting, setIsConnecting] = useState(false);
16
+ const [connectError, setConnectError] = useState(null);
17
+ const [addresses, setAddresses] = useState([]);
18
+ const [walletId, setWalletId] = useState(null);
19
+ const [currentProviderType, setCurrentProviderType] = useState(
20
+ memoizedConfig.providerType || null
21
+ );
22
+ const [isPhantomAvailable, setIsPhantomAvailable] = useState(false);
23
+ const [sdk, setSdk] = useState(null);
22
24
  useEffect(() => {
23
25
  const sdkInstance = new BrowserSDK(memoizedConfig);
24
26
  const handleConnectStart = () => {
@@ -77,19 +79,19 @@ function PhantomProvider({ children, config, debugConfig }) {
77
79
  return;
78
80
  const initialize = async () => {
79
81
  try {
80
- const available = await sdk.waitForPhantomExtension(1e3);
82
+ const available = await BrowserSDK.isPhantomInstalled();
81
83
  setIsPhantomAvailable(available);
82
84
  } catch (err) {
83
85
  console.error("Error checking Phantom extension:", err);
84
86
  setIsPhantomAvailable(false);
85
87
  }
86
- if (config.autoConnect !== false) {
88
+ if (memoizedConfig.autoConnect !== false) {
87
89
  sdk.autoConnect().catch(() => {
88
90
  });
89
91
  }
90
92
  };
91
93
  initialize();
92
- }, [sdk, config.autoConnect]);
94
+ }, [sdk, memoizedConfig.autoConnect]);
93
95
  const value = useMemo(
94
96
  () => ({
95
97
  sdk,
@@ -101,16 +103,7 @@ function PhantomProvider({ children, config, debugConfig }) {
101
103
  currentProviderType,
102
104
  isPhantomAvailable
103
105
  }),
104
- [
105
- sdk,
106
- isConnected,
107
- isConnecting,
108
- connectError,
109
- addresses,
110
- walletId,
111
- currentProviderType,
112
- isPhantomAvailable
113
- ]
106
+ [sdk, isConnected, isConnecting, connectError, addresses, walletId, currentProviderType, isPhantomAvailable]
114
107
  );
115
108
  return /* @__PURE__ */ jsx(PhantomContext.Provider, { value, children });
116
109
  }
@@ -178,115 +171,311 @@ function useDisconnect() {
178
171
  };
179
172
  }
180
173
 
181
- // src/hooks/useSignMessage.ts
182
- import { useCallback as useCallback3, useState as useState3 } from "react";
183
- function useSignMessage() {
184
- const { sdk } = usePhantom();
185
- const [isSigning, setIsSigning] = useState3(false);
186
- const [error, setError] = useState3(null);
187
- const signMessage = useCallback3(
188
- async (params) => {
189
- if (!sdk) {
190
- throw new Error("SDK not initialized");
191
- }
192
- if (!sdk.isConnected()) {
193
- throw new Error("Wallet not connected");
194
- }
195
- setIsSigning(true);
196
- setError(null);
174
+ // src/hooks/useAccounts.ts
175
+ function useAccounts() {
176
+ const { addresses, isConnected } = usePhantom();
177
+ return isConnected ? addresses : null;
178
+ }
179
+
180
+ // src/hooks/useIsExtensionInstalled.ts
181
+ import * as React from "react";
182
+ import { waitForPhantomExtension } from "@phantom/browser-sdk";
183
+ function useIsExtensionInstalled() {
184
+ const [isLoading, setIsLoading] = React.useState(true);
185
+ const [isInstalled, setIsInstalled] = React.useState(false);
186
+ React.useEffect(() => {
187
+ let isMounted = true;
188
+ const checkExtension = async () => {
197
189
  try {
198
- const signature = await sdk.signMessage(params);
199
- return signature;
200
- } catch (err) {
201
- setError(err);
202
- throw err;
190
+ setIsLoading(true);
191
+ const result = await waitForPhantomExtension(3e3);
192
+ if (isMounted) {
193
+ setIsInstalled(result);
194
+ }
195
+ } catch (error) {
196
+ if (isMounted) {
197
+ setIsInstalled(false);
198
+ }
203
199
  } finally {
204
- setIsSigning(false);
200
+ if (isMounted) {
201
+ setIsLoading(false);
202
+ }
205
203
  }
206
- },
207
- [sdk]
208
- );
209
- return {
210
- signMessage,
211
- isSigning,
212
- error
213
- };
204
+ };
205
+ checkExtension();
206
+ return () => {
207
+ isMounted = false;
208
+ };
209
+ }, []);
210
+ return { isLoading, isInstalled };
214
211
  }
215
212
 
216
- // src/hooks/useSignAndSendTransaction.ts
217
- import { useCallback as useCallback4, useState as useState4 } from "react";
218
- function useSignAndSendTransaction() {
219
- const { sdk } = usePhantom();
220
- const [isSigning, setIsSigning] = useState4(false);
213
+ // src/hooks/useAutoConfirm.ts
214
+ import { useCallback as useCallback3, useState as useState4, useEffect as useEffect3 } from "react";
215
+ function useAutoConfirm() {
216
+ const { sdk, currentProviderType } = usePhantom();
217
+ const [status, setStatus] = useState4(null);
218
+ const [supportedChains, setSupportedChains] = useState4(null);
219
+ const [isLoading, setIsLoading] = useState4(false);
221
220
  const [error, setError] = useState4(null);
222
- const signAndSendTransaction = useCallback4(
221
+ const isInjected = currentProviderType === "injected";
222
+ const enable = useCallback3(
223
223
  async (params) => {
224
224
  if (!sdk) {
225
225
  throw new Error("SDK not initialized");
226
226
  }
227
- if (!sdk.isConnected()) {
228
- throw new Error("Wallet not connected");
227
+ if (!isInjected) {
228
+ throw new Error("Auto-confirm is only available for injected (extension) providers");
229
229
  }
230
- setIsSigning(true);
231
- setError(null);
232
230
  try {
233
- const result = await sdk.signAndSendTransaction(params);
231
+ setIsLoading(true);
232
+ setError(null);
233
+ const result = await sdk.enableAutoConfirm(params);
234
+ setStatus(result);
234
235
  return result;
235
236
  } catch (err) {
236
- setError(err);
237
- throw err;
237
+ const error2 = err instanceof Error ? err : new Error("Unknown error occurred");
238
+ setError(error2);
239
+ throw error2;
238
240
  } finally {
239
- setIsSigning(false);
241
+ setIsLoading(false);
240
242
  }
241
243
  },
242
- [sdk]
244
+ [sdk, isInjected]
243
245
  );
246
+ const disable = useCallback3(async () => {
247
+ if (!sdk) {
248
+ throw new Error("SDK not initialized");
249
+ }
250
+ if (!isInjected) {
251
+ throw new Error("Auto-confirm is only available for injected (extension) providers");
252
+ }
253
+ try {
254
+ setIsLoading(true);
255
+ setError(null);
256
+ await sdk.disableAutoConfirm();
257
+ const newStatus = await sdk.getAutoConfirmStatus();
258
+ setStatus(newStatus);
259
+ } catch (err) {
260
+ const error2 = err instanceof Error ? err : new Error("Unknown error occurred");
261
+ setError(error2);
262
+ throw error2;
263
+ } finally {
264
+ setIsLoading(false);
265
+ }
266
+ }, [sdk, isInjected]);
267
+ const refetch = useCallback3(async () => {
268
+ if (!sdk || !isInjected) {
269
+ return;
270
+ }
271
+ try {
272
+ setIsLoading(true);
273
+ setError(null);
274
+ const [statusResult, supportedResult] = await Promise.all([
275
+ sdk.getAutoConfirmStatus(),
276
+ sdk.getSupportedAutoConfirmChains()
277
+ ]);
278
+ setStatus(statusResult);
279
+ setSupportedChains(supportedResult);
280
+ } catch (err) {
281
+ const error2 = err instanceof Error ? err : new Error("Failed to fetch auto-confirm data");
282
+ setError(error2);
283
+ } finally {
284
+ setIsLoading(false);
285
+ }
286
+ }, [sdk, isInjected]);
287
+ useEffect3(() => {
288
+ if (sdk && isInjected) {
289
+ refetch();
290
+ } else {
291
+ setStatus(null);
292
+ setSupportedChains(null);
293
+ setError(null);
294
+ }
295
+ }, [sdk, isInjected, refetch]);
244
296
  return {
245
- signAndSendTransaction,
246
- isSigning,
247
- error
297
+ enable,
298
+ disable,
299
+ status,
300
+ supportedChains,
301
+ isLoading,
302
+ error,
303
+ refetch
248
304
  };
249
305
  }
250
306
 
251
- // src/hooks/useAccounts.ts
252
- function useAccounts() {
253
- const { addresses, isConnected } = usePhantom();
254
- return isConnected ? addresses : null;
307
+ // src/hooks/useSolana.ts
308
+ import { useCallback as useCallback4, useMemo as useMemo2 } from "react";
309
+ function useSolana() {
310
+ const { sdk, isConnected } = usePhantom();
311
+ const solanaChain = useMemo2(() => {
312
+ if (!sdk || !isConnected)
313
+ return null;
314
+ try {
315
+ return sdk.solana;
316
+ } catch {
317
+ return null;
318
+ }
319
+ }, [sdk, isConnected]);
320
+ const signMessage = useCallback4(
321
+ async (message) => {
322
+ if (!solanaChain)
323
+ throw new Error("Solana chain not available. Ensure SDK is connected.");
324
+ return solanaChain.signMessage(message);
325
+ },
326
+ [solanaChain]
327
+ );
328
+ const signTransaction = useCallback4(
329
+ async (transaction) => {
330
+ if (!solanaChain)
331
+ throw new Error("Solana chain not available. Ensure SDK is connected.");
332
+ return solanaChain.signTransaction(transaction);
333
+ },
334
+ [solanaChain]
335
+ );
336
+ const signAndSendTransaction = useCallback4(
337
+ async (transaction) => {
338
+ if (!solanaChain)
339
+ throw new Error("Solana chain not available. Ensure SDK is connected.");
340
+ return solanaChain.signAndSendTransaction(transaction);
341
+ },
342
+ [solanaChain]
343
+ );
344
+ const connect = useCallback4(
345
+ async (options) => {
346
+ if (!solanaChain)
347
+ throw new Error("Solana chain not available. Ensure SDK is connected.");
348
+ return solanaChain.connect(options);
349
+ },
350
+ [solanaChain]
351
+ );
352
+ const disconnect = useCallback4(async () => {
353
+ if (!solanaChain)
354
+ throw new Error("Solana chain not available. Ensure SDK is connected.");
355
+ return solanaChain.disconnect();
356
+ }, [solanaChain]);
357
+ const switchNetwork = useCallback4(
358
+ async (network) => {
359
+ if (!solanaChain)
360
+ throw new Error("Solana chain not available. Ensure SDK is connected.");
361
+ return solanaChain.switchNetwork?.(network);
362
+ },
363
+ [solanaChain]
364
+ );
365
+ const getPublicKey = useCallback4(async () => {
366
+ if (!solanaChain)
367
+ return null;
368
+ return solanaChain.getPublicKey();
369
+ }, [solanaChain]);
370
+ return {
371
+ // Chain instance for advanced usage
372
+ solana: solanaChain,
373
+ // Convenient methods
374
+ signMessage,
375
+ signTransaction,
376
+ signAndSendTransaction,
377
+ connect,
378
+ disconnect,
379
+ switchNetwork,
380
+ getPublicKey,
381
+ // State
382
+ isAvailable: !!solanaChain,
383
+ isConnected: solanaChain?.isConnected() ?? false
384
+ };
255
385
  }
256
386
 
257
- // src/hooks/useIsExtensionInstalled.ts
258
- import * as React from "react";
259
- var cachedIsInstalled = null;
260
- function useIsExtensionInstalled() {
261
- const { sdk } = usePhantom();
262
- const [isLoading, setIsLoading] = React.useState(cachedIsInstalled === null);
263
- const [isInstalled, setIsInstalled] = React.useState(cachedIsInstalled ?? false);
264
- React.useEffect(() => {
265
- if (!sdk) {
266
- setIsLoading(false);
267
- return;
268
- }
269
- if (cachedIsInstalled !== null) {
270
- setIsInstalled(cachedIsInstalled);
271
- setIsLoading(false);
272
- return;
387
+ // src/hooks/useEthereum.ts
388
+ import { useCallback as useCallback5, useMemo as useMemo3 } from "react";
389
+ function useEthereum() {
390
+ const { sdk, isConnected } = usePhantom();
391
+ const ethereumChain = useMemo3(() => {
392
+ if (!sdk || !isConnected)
393
+ return null;
394
+ try {
395
+ return sdk.ethereum;
396
+ } catch {
397
+ return null;
273
398
  }
274
- const checkExtension = async () => {
275
- try {
276
- setIsLoading(true);
277
- const result = await sdk.waitForPhantomExtension(1e3);
278
- cachedIsInstalled = result;
279
- setIsInstalled(result);
280
- } catch (error) {
281
- cachedIsInstalled = false;
282
- setIsInstalled(false);
283
- } finally {
284
- setIsLoading(false);
285
- }
286
- };
287
- checkExtension();
288
- }, [sdk]);
289
- return { isLoading, isInstalled };
399
+ }, [sdk, isConnected]);
400
+ const request = useCallback5(
401
+ async (args) => {
402
+ if (!ethereumChain)
403
+ throw new Error("Ethereum chain not available. Ensure SDK is connected.");
404
+ return ethereumChain.request(args);
405
+ },
406
+ [ethereumChain]
407
+ );
408
+ const signPersonalMessage = useCallback5(
409
+ async (message, address) => {
410
+ return request({
411
+ method: "personal_sign",
412
+ params: [message, address]
413
+ });
414
+ },
415
+ [request]
416
+ );
417
+ const sendTransaction = useCallback5(
418
+ async (transaction) => {
419
+ if (!ethereumChain)
420
+ throw new Error("Ethereum chain not available. Ensure SDK is connected.");
421
+ return ethereumChain.sendTransaction(transaction);
422
+ },
423
+ [ethereumChain]
424
+ );
425
+ const switchChain = useCallback5(
426
+ async (chainId) => {
427
+ if (!ethereumChain)
428
+ throw new Error("Ethereum chain not available. Ensure SDK is connected.");
429
+ return ethereumChain.switchChain(chainId);
430
+ },
431
+ [ethereumChain]
432
+ );
433
+ const getChainId = useCallback5(async () => {
434
+ if (!ethereumChain)
435
+ throw new Error("Ethereum chain not available. Ensure SDK is connected.");
436
+ return ethereumChain.getChainId();
437
+ }, [ethereumChain]);
438
+ const getAccounts = useCallback5(async () => {
439
+ if (!ethereumChain)
440
+ throw new Error("Ethereum chain not available. Ensure SDK is connected.");
441
+ return ethereumChain.getAccounts();
442
+ }, [ethereumChain]);
443
+ const signMessage = useCallback5(
444
+ async (message) => {
445
+ return request({
446
+ method: "eth_sign",
447
+ params: [await getAccounts().then((accounts) => accounts[0]), message]
448
+ });
449
+ },
450
+ [request, getAccounts]
451
+ );
452
+ const signTypedData = useCallback5(
453
+ async (typedData) => {
454
+ const accounts = await getAccounts();
455
+ return request({
456
+ method: "eth_signTypedData_v4",
457
+ params: [accounts[0], JSON.stringify(typedData)]
458
+ });
459
+ },
460
+ [request, getAccounts]
461
+ );
462
+ return {
463
+ // Chain instance for advanced usage
464
+ ethereum: ethereumChain,
465
+ // Standard EIP-1193 interface
466
+ request,
467
+ // Convenient methods
468
+ signPersonalMessage,
469
+ signMessage,
470
+ signTypedData,
471
+ sendTransaction,
472
+ switchChain,
473
+ getChainId,
474
+ getAccounts,
475
+ // State
476
+ isAvailable: !!ethereumChain,
477
+ isConnected: ethereumChain?.isConnected() ?? false
478
+ };
290
479
  }
291
480
 
292
481
  // src/index.ts
@@ -298,10 +487,11 @@ export {
298
487
  PhantomProvider,
299
488
  debug,
300
489
  useAccounts,
490
+ useAutoConfirm,
301
491
  useConnect,
302
492
  useDisconnect,
493
+ useEthereum,
303
494
  useIsExtensionInstalled,
304
495
  usePhantom,
305
- useSignAndSendTransaction,
306
- useSignMessage
496
+ useSolana
307
497
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phantom/react-sdk",
3
- "version": "0.3.9",
3
+ "version": "1.0.0-beta.1",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",
@@ -26,7 +26,9 @@
26
26
  "prettier": "prettier --write \"src/**/*.{ts,tsx}\""
27
27
  },
28
28
  "dependencies": {
29
- "@phantom/browser-sdk": "^0.3.9"
29
+ "@phantom/browser-sdk": "^1.0.0-beta.1",
30
+ "@phantom/chains": "^1.0.0-beta.1",
31
+ "@phantom/constants": "^1.0.0-beta.1"
30
32
  },
31
33
  "devDependencies": {
32
34
  "@testing-library/dom": "^10.4.0",