@phantom/react-sdk 1.0.0-beta.0 → 1.0.0-beta.10
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 +66 -112
- package/dist/index.d.ts +11 -33
- package/dist/index.js +119 -235
- package/dist/index.mjs +120 -236
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -52,23 +52,30 @@ var import_browser_sdk = require("@phantom/browser-sdk");
|
|
|
52
52
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
53
53
|
var PhantomContext = (0, import_react.createContext)(void 0);
|
|
54
54
|
function PhantomProvider({ children, config, debugConfig }) {
|
|
55
|
+
const memoizedConfig = (0, import_react.useMemo)(() => config, [config]);
|
|
56
|
+
const [sdk, setSdk] = (0, import_react.useState)(null);
|
|
57
|
+
const [isClient, setIsClient] = (0, import_react.useState)(false);
|
|
55
58
|
const [isConnected, setIsConnected] = (0, import_react.useState)(false);
|
|
56
59
|
const [isConnecting, setIsConnecting] = (0, import_react.useState)(false);
|
|
57
60
|
const [connectError, setConnectError] = (0, import_react.useState)(null);
|
|
58
61
|
const [addresses, setAddresses] = (0, import_react.useState)([]);
|
|
59
62
|
const [walletId, setWalletId] = (0, import_react.useState)(null);
|
|
60
|
-
const [currentProviderType, setCurrentProviderType] = (0, import_react.useState)(
|
|
63
|
+
const [currentProviderType, setCurrentProviderType] = (0, import_react.useState)(
|
|
64
|
+
memoizedConfig.providerType || null
|
|
65
|
+
);
|
|
61
66
|
const [isPhantomAvailable, setIsPhantomAvailable] = (0, import_react.useState)(false);
|
|
62
|
-
const [sdk, setSdk] = (0, import_react.useState)(null);
|
|
63
|
-
const memoizedConfig = (0, import_react.useMemo)(() => {
|
|
64
|
-
return {
|
|
65
|
-
...config,
|
|
66
|
-
// Use providerType if provided, default to embedded
|
|
67
|
-
providerType: config.providerType || "embedded"
|
|
68
|
-
};
|
|
69
|
-
}, [config]);
|
|
70
67
|
(0, import_react.useEffect)(() => {
|
|
68
|
+
setIsClient(true);
|
|
69
|
+
}, []);
|
|
70
|
+
(0, import_react.useEffect)(() => {
|
|
71
|
+
if (!isClient)
|
|
72
|
+
return;
|
|
71
73
|
const sdkInstance = new import_browser_sdk.BrowserSDK(memoizedConfig);
|
|
74
|
+
setSdk(sdkInstance);
|
|
75
|
+
}, [isClient, memoizedConfig]);
|
|
76
|
+
(0, import_react.useEffect)(() => {
|
|
77
|
+
if (!sdk)
|
|
78
|
+
return;
|
|
72
79
|
const handleConnectStart = () => {
|
|
73
80
|
setIsConnecting(true);
|
|
74
81
|
setConnectError(null);
|
|
@@ -77,15 +84,15 @@ function PhantomProvider({ children, config, debugConfig }) {
|
|
|
77
84
|
try {
|
|
78
85
|
setIsConnected(true);
|
|
79
86
|
setIsConnecting(false);
|
|
80
|
-
const providerInfo =
|
|
87
|
+
const providerInfo = sdk.getCurrentProviderInfo();
|
|
81
88
|
setCurrentProviderType(providerInfo?.type || null);
|
|
82
|
-
const addrs = await
|
|
89
|
+
const addrs = await sdk.getAddresses();
|
|
83
90
|
setAddresses(addrs);
|
|
84
|
-
setWalletId(
|
|
91
|
+
setWalletId(sdk.getWalletId());
|
|
85
92
|
} catch (err) {
|
|
86
93
|
console.error("Error connecting:", err);
|
|
87
94
|
try {
|
|
88
|
-
await
|
|
95
|
+
await sdk.disconnect();
|
|
89
96
|
} catch (err2) {
|
|
90
97
|
console.error("Error disconnecting:", err2);
|
|
91
98
|
}
|
|
@@ -103,41 +110,40 @@ function PhantomProvider({ children, config, debugConfig }) {
|
|
|
103
110
|
setAddresses([]);
|
|
104
111
|
setWalletId(null);
|
|
105
112
|
};
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
setSdk(sdkInstance);
|
|
113
|
+
sdk.on("connect_start", handleConnectStart);
|
|
114
|
+
sdk.on("connect", handleConnect);
|
|
115
|
+
sdk.on("connect_error", handleConnectError);
|
|
116
|
+
sdk.on("disconnect", handleDisconnect);
|
|
111
117
|
return () => {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
118
|
+
sdk.off("connect_start", handleConnectStart);
|
|
119
|
+
sdk.off("connect", handleConnect);
|
|
120
|
+
sdk.off("connect_error", handleConnectError);
|
|
121
|
+
sdk.off("disconnect", handleDisconnect);
|
|
116
122
|
};
|
|
117
|
-
}, [
|
|
123
|
+
}, [sdk]);
|
|
118
124
|
(0, import_react.useEffect)(() => {
|
|
119
|
-
if (!
|
|
125
|
+
if (!debugConfig || !sdk)
|
|
120
126
|
return;
|
|
121
127
|
sdk.configureDebug(debugConfig);
|
|
122
128
|
}, [sdk, debugConfig]);
|
|
123
129
|
(0, import_react.useEffect)(() => {
|
|
124
|
-
if (!sdk)
|
|
130
|
+
if (!isClient || !sdk)
|
|
125
131
|
return;
|
|
126
|
-
const initialize = () => {
|
|
132
|
+
const initialize = async () => {
|
|
127
133
|
try {
|
|
128
|
-
const available = import_browser_sdk.BrowserSDK.isPhantomInstalled();
|
|
134
|
+
const available = await import_browser_sdk.BrowserSDK.isPhantomInstalled();
|
|
129
135
|
setIsPhantomAvailable(available);
|
|
130
136
|
} catch (err) {
|
|
131
137
|
console.error("Error checking Phantom extension:", err);
|
|
132
138
|
setIsPhantomAvailable(false);
|
|
133
139
|
}
|
|
134
|
-
if (
|
|
140
|
+
if (memoizedConfig.autoConnect !== false) {
|
|
135
141
|
sdk.autoConnect().catch(() => {
|
|
136
142
|
});
|
|
137
143
|
}
|
|
138
144
|
};
|
|
139
145
|
initialize();
|
|
140
|
-
}, [sdk,
|
|
146
|
+
}, [sdk, memoizedConfig.autoConnect, isClient]);
|
|
141
147
|
const value = (0, import_react.useMemo)(
|
|
142
148
|
() => ({
|
|
143
149
|
sdk,
|
|
@@ -147,18 +153,10 @@ function PhantomProvider({ children, config, debugConfig }) {
|
|
|
147
153
|
addresses,
|
|
148
154
|
walletId,
|
|
149
155
|
currentProviderType,
|
|
150
|
-
isPhantomAvailable
|
|
156
|
+
isPhantomAvailable,
|
|
157
|
+
isClient
|
|
151
158
|
}),
|
|
152
|
-
[
|
|
153
|
-
sdk,
|
|
154
|
-
isConnected,
|
|
155
|
-
isConnecting,
|
|
156
|
-
connectError,
|
|
157
|
-
addresses,
|
|
158
|
-
walletId,
|
|
159
|
-
currentProviderType,
|
|
160
|
-
isPhantomAvailable
|
|
161
|
-
]
|
|
159
|
+
[sdk, isConnected, isConnecting, connectError, addresses, walletId, currentProviderType, isPhantomAvailable, isClient]
|
|
162
160
|
);
|
|
163
161
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PhantomContext.Provider, { value, children });
|
|
164
162
|
}
|
|
@@ -235,36 +233,33 @@ function useAccounts() {
|
|
|
235
233
|
// src/hooks/useIsExtensionInstalled.ts
|
|
236
234
|
var React = __toESM(require("react"));
|
|
237
235
|
var import_browser_sdk2 = require("@phantom/browser-sdk");
|
|
238
|
-
var cachedIsInstalled = null;
|
|
239
236
|
function useIsExtensionInstalled() {
|
|
240
|
-
const
|
|
241
|
-
const [
|
|
242
|
-
const [isInstalled, setIsInstalled] = React.useState(cachedIsInstalled ?? false);
|
|
237
|
+
const [isLoading, setIsLoading] = React.useState(true);
|
|
238
|
+
const [isInstalled, setIsInstalled] = React.useState(false);
|
|
243
239
|
React.useEffect(() => {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
return;
|
|
247
|
-
}
|
|
248
|
-
if (cachedIsInstalled !== null) {
|
|
249
|
-
setIsInstalled(cachedIsInstalled);
|
|
250
|
-
setIsLoading(false);
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
253
|
-
const checkExtension = () => {
|
|
240
|
+
let isMounted = true;
|
|
241
|
+
const checkExtension = async () => {
|
|
254
242
|
try {
|
|
255
243
|
setIsLoading(true);
|
|
256
|
-
const result = import_browser_sdk2.
|
|
257
|
-
|
|
258
|
-
|
|
244
|
+
const result = await (0, import_browser_sdk2.waitForPhantomExtension)(3e3);
|
|
245
|
+
if (isMounted) {
|
|
246
|
+
setIsInstalled(result);
|
|
247
|
+
}
|
|
259
248
|
} catch (error) {
|
|
260
|
-
|
|
261
|
-
|
|
249
|
+
if (isMounted) {
|
|
250
|
+
setIsInstalled(false);
|
|
251
|
+
}
|
|
262
252
|
} finally {
|
|
263
|
-
|
|
253
|
+
if (isMounted) {
|
|
254
|
+
setIsLoading(false);
|
|
255
|
+
}
|
|
264
256
|
}
|
|
265
257
|
};
|
|
266
258
|
checkExtension();
|
|
267
|
-
|
|
259
|
+
return () => {
|
|
260
|
+
isMounted = false;
|
|
261
|
+
};
|
|
262
|
+
}, []);
|
|
268
263
|
return { isLoading, isInstalled };
|
|
269
264
|
}
|
|
270
265
|
|
|
@@ -301,53 +296,47 @@ function useAutoConfirm() {
|
|
|
301
296
|
},
|
|
302
297
|
[sdk, isInjected]
|
|
303
298
|
);
|
|
304
|
-
const disable = (0, import_react4.useCallback)(
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
} finally {
|
|
346
|
-
setIsLoading(false);
|
|
347
|
-
}
|
|
348
|
-
},
|
|
349
|
-
[sdk, isInjected]
|
|
350
|
-
);
|
|
299
|
+
const disable = (0, import_react4.useCallback)(async () => {
|
|
300
|
+
if (!sdk) {
|
|
301
|
+
throw new Error("SDK not initialized");
|
|
302
|
+
}
|
|
303
|
+
if (!isInjected) {
|
|
304
|
+
throw new Error("Auto-confirm is only available for injected (extension) providers");
|
|
305
|
+
}
|
|
306
|
+
try {
|
|
307
|
+
setIsLoading(true);
|
|
308
|
+
setError(null);
|
|
309
|
+
await sdk.disableAutoConfirm();
|
|
310
|
+
const newStatus = await sdk.getAutoConfirmStatus();
|
|
311
|
+
setStatus(newStatus);
|
|
312
|
+
} catch (err) {
|
|
313
|
+
const error2 = err instanceof Error ? err : new Error("Unknown error occurred");
|
|
314
|
+
setError(error2);
|
|
315
|
+
throw error2;
|
|
316
|
+
} finally {
|
|
317
|
+
setIsLoading(false);
|
|
318
|
+
}
|
|
319
|
+
}, [sdk, isInjected]);
|
|
320
|
+
const refetch = (0, import_react4.useCallback)(async () => {
|
|
321
|
+
if (!sdk || !isInjected) {
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
try {
|
|
325
|
+
setIsLoading(true);
|
|
326
|
+
setError(null);
|
|
327
|
+
const [statusResult, supportedResult] = await Promise.all([
|
|
328
|
+
sdk.getAutoConfirmStatus(),
|
|
329
|
+
sdk.getSupportedAutoConfirmChains()
|
|
330
|
+
]);
|
|
331
|
+
setStatus(statusResult);
|
|
332
|
+
setSupportedChains(supportedResult);
|
|
333
|
+
} catch (err) {
|
|
334
|
+
const error2 = err instanceof Error ? err : new Error("Failed to fetch auto-confirm data");
|
|
335
|
+
setError(error2);
|
|
336
|
+
} finally {
|
|
337
|
+
setIsLoading(false);
|
|
338
|
+
}
|
|
339
|
+
}, [sdk, isInjected]);
|
|
351
340
|
(0, import_react4.useEffect)(() => {
|
|
352
341
|
if (sdk && isInjected) {
|
|
353
342
|
refetch();
|
|
@@ -369,143 +358,38 @@ function useAutoConfirm() {
|
|
|
369
358
|
}
|
|
370
359
|
|
|
371
360
|
// src/hooks/useSolana.ts
|
|
372
|
-
var import_react5 = require("react");
|
|
373
361
|
function useSolana() {
|
|
374
|
-
const { sdk, isConnected } = usePhantom();
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
}
|
|
383
|
-
}, [sdk, isConnected]);
|
|
384
|
-
const signMessage = (0, import_react5.useCallback)(async (message) => {
|
|
385
|
-
if (!solanaChain)
|
|
386
|
-
throw new Error("Solana chain not available. Ensure SDK is connected.");
|
|
387
|
-
return solanaChain.signMessage(message);
|
|
388
|
-
}, [solanaChain]);
|
|
389
|
-
const signTransaction = (0, import_react5.useCallback)(async (transaction) => {
|
|
390
|
-
if (!solanaChain)
|
|
391
|
-
throw new Error("Solana chain not available. Ensure SDK is connected.");
|
|
392
|
-
return solanaChain.signTransaction(transaction);
|
|
393
|
-
}, [solanaChain]);
|
|
394
|
-
const signAndSendTransaction = (0, import_react5.useCallback)(async (transaction) => {
|
|
395
|
-
if (!solanaChain)
|
|
396
|
-
throw new Error("Solana chain not available. Ensure SDK is connected.");
|
|
397
|
-
return solanaChain.signAndSendTransaction(transaction);
|
|
398
|
-
}, [solanaChain]);
|
|
399
|
-
const connect = (0, import_react5.useCallback)(async (options) => {
|
|
400
|
-
if (!solanaChain)
|
|
401
|
-
throw new Error("Solana chain not available. Ensure SDK is connected.");
|
|
402
|
-
return solanaChain.connect(options);
|
|
403
|
-
}, [solanaChain]);
|
|
404
|
-
const disconnect = (0, import_react5.useCallback)(async () => {
|
|
405
|
-
if (!solanaChain)
|
|
406
|
-
throw new Error("Solana chain not available. Ensure SDK is connected.");
|
|
407
|
-
return solanaChain.disconnect();
|
|
408
|
-
}, [solanaChain]);
|
|
409
|
-
const switchNetwork = (0, import_react5.useCallback)(async (network) => {
|
|
410
|
-
if (!solanaChain)
|
|
411
|
-
throw new Error("Solana chain not available. Ensure SDK is connected.");
|
|
412
|
-
return solanaChain.switchNetwork(network);
|
|
413
|
-
}, [solanaChain]);
|
|
414
|
-
const getPublicKey = (0, import_react5.useCallback)(async () => {
|
|
415
|
-
if (!solanaChain)
|
|
416
|
-
return null;
|
|
417
|
-
return solanaChain.getPublicKey();
|
|
418
|
-
}, [solanaChain]);
|
|
362
|
+
const { sdk, isConnected, isClient } = usePhantom();
|
|
363
|
+
if (!isClient || !sdk) {
|
|
364
|
+
return {
|
|
365
|
+
solana: {},
|
|
366
|
+
// This will be replaced when SDK is ready
|
|
367
|
+
isAvailable: false
|
|
368
|
+
};
|
|
369
|
+
}
|
|
419
370
|
return {
|
|
420
|
-
// Chain instance for
|
|
421
|
-
solana:
|
|
422
|
-
// Convenient methods
|
|
423
|
-
signMessage,
|
|
424
|
-
signTransaction,
|
|
425
|
-
signAndSendTransaction,
|
|
426
|
-
connect,
|
|
427
|
-
disconnect,
|
|
428
|
-
switchNetwork,
|
|
429
|
-
getPublicKey,
|
|
371
|
+
// Chain instance with connection enforcement for signing methods
|
|
372
|
+
solana: sdk.solana,
|
|
430
373
|
// State
|
|
431
|
-
isAvailable: !!
|
|
432
|
-
isConnected: solanaChain?.isConnected() ?? false
|
|
374
|
+
isAvailable: !!isConnected
|
|
433
375
|
};
|
|
434
376
|
}
|
|
435
377
|
|
|
436
378
|
// src/hooks/useEthereum.ts
|
|
437
|
-
var import_react6 = require("react");
|
|
438
379
|
function useEthereum() {
|
|
439
|
-
const { sdk, isConnected } = usePhantom();
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
}
|
|
448
|
-
}, [sdk, isConnected]);
|
|
449
|
-
const request = (0, import_react6.useCallback)(async (args) => {
|
|
450
|
-
if (!ethereumChain)
|
|
451
|
-
throw new Error("Ethereum chain not available. Ensure SDK is connected.");
|
|
452
|
-
return ethereumChain.request(args);
|
|
453
|
-
}, [ethereumChain]);
|
|
454
|
-
const signPersonalMessage = (0, import_react6.useCallback)(async (message, address) => {
|
|
455
|
-
return request({
|
|
456
|
-
method: "personal_sign",
|
|
457
|
-
params: [message, address]
|
|
458
|
-
});
|
|
459
|
-
}, [request]);
|
|
460
|
-
const sendTransaction = (0, import_react6.useCallback)(async (transaction) => {
|
|
461
|
-
if (!ethereumChain)
|
|
462
|
-
throw new Error("Ethereum chain not available. Ensure SDK is connected.");
|
|
463
|
-
return ethereumChain.sendTransaction(transaction);
|
|
464
|
-
}, [ethereumChain]);
|
|
465
|
-
const switchChain = (0, import_react6.useCallback)(async (chainId) => {
|
|
466
|
-
if (!ethereumChain)
|
|
467
|
-
throw new Error("Ethereum chain not available. Ensure SDK is connected.");
|
|
468
|
-
return ethereumChain.switchChain(chainId);
|
|
469
|
-
}, [ethereumChain]);
|
|
470
|
-
const getChainId = (0, import_react6.useCallback)(async () => {
|
|
471
|
-
if (!ethereumChain)
|
|
472
|
-
throw new Error("Ethereum chain not available. Ensure SDK is connected.");
|
|
473
|
-
return ethereumChain.getChainId();
|
|
474
|
-
}, [ethereumChain]);
|
|
475
|
-
const getAccounts = (0, import_react6.useCallback)(async () => {
|
|
476
|
-
if (!ethereumChain)
|
|
477
|
-
throw new Error("Ethereum chain not available. Ensure SDK is connected.");
|
|
478
|
-
return ethereumChain.getAccounts();
|
|
479
|
-
}, [ethereumChain]);
|
|
480
|
-
const signMessage = (0, import_react6.useCallback)(async (message) => {
|
|
481
|
-
return request({
|
|
482
|
-
method: "eth_sign",
|
|
483
|
-
params: [await getAccounts().then((accounts) => accounts[0]), message]
|
|
484
|
-
});
|
|
485
|
-
}, [request, getAccounts]);
|
|
486
|
-
const signTypedData = (0, import_react6.useCallback)(async (typedData) => {
|
|
487
|
-
const accounts = await getAccounts();
|
|
488
|
-
return request({
|
|
489
|
-
method: "eth_signTypedData_v4",
|
|
490
|
-
params: [accounts[0], JSON.stringify(typedData)]
|
|
491
|
-
});
|
|
492
|
-
}, [request, getAccounts]);
|
|
380
|
+
const { sdk, isConnected, isClient } = usePhantom();
|
|
381
|
+
if (!isClient || !sdk) {
|
|
382
|
+
return {
|
|
383
|
+
ethereum: {},
|
|
384
|
+
// This will be replaced when SDK is ready
|
|
385
|
+
isAvailable: false
|
|
386
|
+
};
|
|
387
|
+
}
|
|
493
388
|
return {
|
|
494
|
-
// Chain instance for
|
|
495
|
-
ethereum:
|
|
496
|
-
// Standard EIP-1193 interface
|
|
497
|
-
request,
|
|
498
|
-
// Convenient methods
|
|
499
|
-
signPersonalMessage,
|
|
500
|
-
signMessage,
|
|
501
|
-
signTypedData,
|
|
502
|
-
sendTransaction,
|
|
503
|
-
switchChain,
|
|
504
|
-
getChainId,
|
|
505
|
-
getAccounts,
|
|
389
|
+
// Chain instance with connection enforcement for signing methods
|
|
390
|
+
ethereum: sdk.ethereum,
|
|
506
391
|
// State
|
|
507
|
-
isAvailable: !!
|
|
508
|
-
isConnected: ethereumChain?.isConnected() ?? false
|
|
392
|
+
isAvailable: !!isConnected
|
|
509
393
|
};
|
|
510
394
|
}
|
|
511
395
|
|