@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/README.md +409 -267
- package/dist/index.d.ts +70 -16
- package/dist/index.js +300 -110
- package/dist/index.mjs +297 -107
- package/package.json +4 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import { BrowserSDKConfig, DebugConfig, AuthOptions, BrowserSDK, WalletAddress,
|
|
4
|
-
export { AddressType,
|
|
3
|
+
import { BrowserSDKConfig, DebugConfig, AuthOptions, BrowserSDK, WalletAddress, AutoConfirmEnableParams, AutoConfirmResult, AutoConfirmSupportedChainsResult } from '@phantom/browser-sdk';
|
|
4
|
+
export { AddressType, AutoConfirmEnableParams, AutoConfirmResult, AutoConfirmSupportedChainsResult, DebugLevel, DebugMessage, NetworkId, SignedTransaction, WalletAddress, debug } from '@phantom/browser-sdk';
|
|
5
5
|
import * as _phantom_embedded_provider_core from '@phantom/embedded-provider-core';
|
|
6
|
+
import { ISolanaChain, IEthereumChain, EthTransactionRequest } from '@phantom/chains';
|
|
7
|
+
export { EthTransactionRequest, IEthereumChain, ISolanaChain } from '@phantom/chains';
|
|
6
8
|
|
|
7
9
|
interface PhantomSDKConfig extends BrowserSDKConfig {
|
|
8
10
|
}
|
|
@@ -32,7 +34,7 @@ declare function PhantomProvider({ children, config, debugConfig }: PhantomProvi
|
|
|
32
34
|
declare function usePhantom(): PhantomContextValue;
|
|
33
35
|
|
|
34
36
|
declare function useConnect(): {
|
|
35
|
-
connect: (options?:
|
|
37
|
+
connect: (options?: AuthOptions) => Promise<_phantom_embedded_provider_core.ConnectResult>;
|
|
36
38
|
isConnecting: boolean;
|
|
37
39
|
error: Error | null;
|
|
38
40
|
currentProviderType: "injected" | "embedded" | null;
|
|
@@ -45,25 +47,77 @@ declare function useDisconnect(): {
|
|
|
45
47
|
error: Error | null;
|
|
46
48
|
};
|
|
47
49
|
|
|
48
|
-
declare function useSignMessage(): {
|
|
49
|
-
signMessage: (params: SignMessageParams) => Promise<SignMessageResult>;
|
|
50
|
-
isSigning: boolean;
|
|
51
|
-
error: Error | null;
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
declare function useSignAndSendTransaction(): {
|
|
55
|
-
signAndSendTransaction: (params: SignAndSendTransactionParams) => Promise<SignedTransaction>;
|
|
56
|
-
isSigning: boolean;
|
|
57
|
-
error: Error | null;
|
|
58
|
-
};
|
|
59
|
-
|
|
60
50
|
declare function useAccounts(): _phantom_embedded_provider_core.WalletAddress[] | null;
|
|
61
51
|
|
|
52
|
+
/**
|
|
53
|
+
* React hook to check if Phantom extension is installed
|
|
54
|
+
* Uses waitForPhantomExtension for proper detection with retry logic
|
|
55
|
+
*/
|
|
62
56
|
declare function useIsExtensionInstalled(): {
|
|
63
57
|
isLoading: boolean;
|
|
64
58
|
isInstalled: boolean;
|
|
65
59
|
};
|
|
66
60
|
|
|
61
|
+
interface UseAutoConfirmResult {
|
|
62
|
+
enable: (params: AutoConfirmEnableParams) => Promise<AutoConfirmResult>;
|
|
63
|
+
disable: () => Promise<void>;
|
|
64
|
+
status: AutoConfirmResult | null;
|
|
65
|
+
supportedChains: AutoConfirmSupportedChainsResult | null;
|
|
66
|
+
isLoading: boolean;
|
|
67
|
+
error: Error | null;
|
|
68
|
+
refetch: () => Promise<void>;
|
|
69
|
+
}
|
|
70
|
+
declare function useAutoConfirm(): UseAutoConfirmResult;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Hook for Solana chain operations
|
|
74
|
+
*
|
|
75
|
+
* @returns Solana chain interface and convenient methods
|
|
76
|
+
*/
|
|
77
|
+
declare function useSolana(): {
|
|
78
|
+
solana: ISolanaChain | null;
|
|
79
|
+
signMessage: (message: string | Uint8Array) => Promise<{
|
|
80
|
+
signature: Uint8Array;
|
|
81
|
+
publicKey: string;
|
|
82
|
+
}>;
|
|
83
|
+
signTransaction: <T>(transaction: T) => Promise<T>;
|
|
84
|
+
signAndSendTransaction: <T>(transaction: T) => Promise<{
|
|
85
|
+
signature: string;
|
|
86
|
+
}>;
|
|
87
|
+
connect: (options?: {
|
|
88
|
+
onlyIfTrusted?: boolean;
|
|
89
|
+
}) => Promise<{
|
|
90
|
+
publicKey: string;
|
|
91
|
+
}>;
|
|
92
|
+
disconnect: () => Promise<void>;
|
|
93
|
+
switchNetwork: (network: "mainnet" | "devnet") => Promise<void | undefined>;
|
|
94
|
+
getPublicKey: () => Promise<string | null>;
|
|
95
|
+
isAvailable: boolean;
|
|
96
|
+
isConnected: boolean;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Hook for Ethereum chain operations
|
|
101
|
+
*
|
|
102
|
+
* @returns Ethereum chain interface and convenient methods
|
|
103
|
+
*/
|
|
104
|
+
declare function useEthereum(): {
|
|
105
|
+
ethereum: IEthereumChain | null;
|
|
106
|
+
request: <T = any>(args: {
|
|
107
|
+
method: string;
|
|
108
|
+
params?: unknown[];
|
|
109
|
+
}) => Promise<T>;
|
|
110
|
+
signPersonalMessage: (message: string, address: string) => Promise<string>;
|
|
111
|
+
signMessage: (message: string) => Promise<string>;
|
|
112
|
+
signTypedData: (typedData: any) => Promise<string>;
|
|
113
|
+
sendTransaction: (transaction: EthTransactionRequest) => Promise<string>;
|
|
114
|
+
switchChain: (chainId: number) => Promise<void>;
|
|
115
|
+
getChainId: () => Promise<number>;
|
|
116
|
+
getAccounts: () => Promise<string[]>;
|
|
117
|
+
isAvailable: boolean;
|
|
118
|
+
isConnected: boolean;
|
|
119
|
+
};
|
|
120
|
+
|
|
67
121
|
type ProviderType = "injected" | "embedded";
|
|
68
122
|
|
|
69
|
-
export { ConnectOptions, PhantomDebugConfig, PhantomProvider, PhantomProviderProps, PhantomSDKConfig, ProviderType, useAccounts, useConnect, useDisconnect, useIsExtensionInstalled, usePhantom,
|
|
123
|
+
export { ConnectOptions, PhantomDebugConfig, PhantomProvider, PhantomProviderProps, PhantomSDKConfig, ProviderType, useAccounts, useAutoConfirm, useConnect, useDisconnect, useEthereum, useIsExtensionInstalled, usePhantom, useSolana };
|
package/dist/index.js
CHANGED
|
@@ -30,18 +30,19 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var src_exports = {};
|
|
32
32
|
__export(src_exports, {
|
|
33
|
-
AddressType: () =>
|
|
34
|
-
DebugLevel: () =>
|
|
35
|
-
NetworkId: () =>
|
|
33
|
+
AddressType: () => import_browser_sdk3.AddressType,
|
|
34
|
+
DebugLevel: () => import_browser_sdk3.DebugLevel,
|
|
35
|
+
NetworkId: () => import_browser_sdk3.NetworkId,
|
|
36
36
|
PhantomProvider: () => PhantomProvider,
|
|
37
|
-
debug: () =>
|
|
37
|
+
debug: () => import_browser_sdk3.debug,
|
|
38
38
|
useAccounts: () => useAccounts,
|
|
39
|
+
useAutoConfirm: () => useAutoConfirm,
|
|
39
40
|
useConnect: () => useConnect,
|
|
40
41
|
useDisconnect: () => useDisconnect,
|
|
42
|
+
useEthereum: () => useEthereum,
|
|
41
43
|
useIsExtensionInstalled: () => useIsExtensionInstalled,
|
|
42
44
|
usePhantom: () => usePhantom,
|
|
43
|
-
|
|
44
|
-
useSignMessage: () => useSignMessage
|
|
45
|
+
useSolana: () => useSolana
|
|
45
46
|
});
|
|
46
47
|
module.exports = __toCommonJS(src_exports);
|
|
47
48
|
|
|
@@ -51,14 +52,6 @@ var import_browser_sdk = require("@phantom/browser-sdk");
|
|
|
51
52
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
52
53
|
var PhantomContext = (0, import_react.createContext)(void 0);
|
|
53
54
|
function PhantomProvider({ children, config, debugConfig }) {
|
|
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);
|
|
57
|
-
const [addresses, setAddresses] = (0, import_react.useState)([]);
|
|
58
|
-
const [walletId, setWalletId] = (0, import_react.useState)(null);
|
|
59
|
-
const [currentProviderType, setCurrentProviderType] = (0, import_react.useState)(config.providerType || null);
|
|
60
|
-
const [isPhantomAvailable, setIsPhantomAvailable] = (0, import_react.useState)(false);
|
|
61
|
-
const [sdk, setSdk] = (0, import_react.useState)(null);
|
|
62
55
|
const memoizedConfig = (0, import_react.useMemo)(() => {
|
|
63
56
|
return {
|
|
64
57
|
...config,
|
|
@@ -66,6 +59,16 @@ function PhantomProvider({ children, config, debugConfig }) {
|
|
|
66
59
|
providerType: config.providerType || "embedded"
|
|
67
60
|
};
|
|
68
61
|
}, [config]);
|
|
62
|
+
const [isConnected, setIsConnected] = (0, import_react.useState)(false);
|
|
63
|
+
const [isConnecting, setIsConnecting] = (0, import_react.useState)(false);
|
|
64
|
+
const [connectError, setConnectError] = (0, import_react.useState)(null);
|
|
65
|
+
const [addresses, setAddresses] = (0, import_react.useState)([]);
|
|
66
|
+
const [walletId, setWalletId] = (0, import_react.useState)(null);
|
|
67
|
+
const [currentProviderType, setCurrentProviderType] = (0, import_react.useState)(
|
|
68
|
+
memoizedConfig.providerType || null
|
|
69
|
+
);
|
|
70
|
+
const [isPhantomAvailable, setIsPhantomAvailable] = (0, import_react.useState)(false);
|
|
71
|
+
const [sdk, setSdk] = (0, import_react.useState)(null);
|
|
69
72
|
(0, import_react.useEffect)(() => {
|
|
70
73
|
const sdkInstance = new import_browser_sdk.BrowserSDK(memoizedConfig);
|
|
71
74
|
const handleConnectStart = () => {
|
|
@@ -124,19 +127,19 @@ function PhantomProvider({ children, config, debugConfig }) {
|
|
|
124
127
|
return;
|
|
125
128
|
const initialize = async () => {
|
|
126
129
|
try {
|
|
127
|
-
const available = await
|
|
130
|
+
const available = await import_browser_sdk.BrowserSDK.isPhantomInstalled();
|
|
128
131
|
setIsPhantomAvailable(available);
|
|
129
132
|
} catch (err) {
|
|
130
133
|
console.error("Error checking Phantom extension:", err);
|
|
131
134
|
setIsPhantomAvailable(false);
|
|
132
135
|
}
|
|
133
|
-
if (
|
|
136
|
+
if (memoizedConfig.autoConnect !== false) {
|
|
134
137
|
sdk.autoConnect().catch(() => {
|
|
135
138
|
});
|
|
136
139
|
}
|
|
137
140
|
};
|
|
138
141
|
initialize();
|
|
139
|
-
}, [sdk,
|
|
142
|
+
}, [sdk, memoizedConfig.autoConnect]);
|
|
140
143
|
const value = (0, import_react.useMemo)(
|
|
141
144
|
() => ({
|
|
142
145
|
sdk,
|
|
@@ -148,16 +151,7 @@ function PhantomProvider({ children, config, debugConfig }) {
|
|
|
148
151
|
currentProviderType,
|
|
149
152
|
isPhantomAvailable
|
|
150
153
|
}),
|
|
151
|
-
[
|
|
152
|
-
sdk,
|
|
153
|
-
isConnected,
|
|
154
|
-
isConnecting,
|
|
155
|
-
connectError,
|
|
156
|
-
addresses,
|
|
157
|
-
walletId,
|
|
158
|
-
currentProviderType,
|
|
159
|
-
isPhantomAvailable
|
|
160
|
-
]
|
|
154
|
+
[sdk, isConnected, isConnecting, connectError, addresses, walletId, currentProviderType, isPhantomAvailable]
|
|
161
155
|
);
|
|
162
156
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PhantomContext.Provider, { value, children });
|
|
163
157
|
}
|
|
@@ -225,116 +219,312 @@ function useDisconnect() {
|
|
|
225
219
|
};
|
|
226
220
|
}
|
|
227
221
|
|
|
228
|
-
// src/hooks/
|
|
222
|
+
// src/hooks/useAccounts.ts
|
|
223
|
+
function useAccounts() {
|
|
224
|
+
const { addresses, isConnected } = usePhantom();
|
|
225
|
+
return isConnected ? addresses : null;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// src/hooks/useIsExtensionInstalled.ts
|
|
229
|
+
var React = __toESM(require("react"));
|
|
230
|
+
var import_browser_sdk2 = require("@phantom/browser-sdk");
|
|
231
|
+
function useIsExtensionInstalled() {
|
|
232
|
+
const [isLoading, setIsLoading] = React.useState(true);
|
|
233
|
+
const [isInstalled, setIsInstalled] = React.useState(false);
|
|
234
|
+
React.useEffect(() => {
|
|
235
|
+
let isMounted = true;
|
|
236
|
+
const checkExtension = async () => {
|
|
237
|
+
try {
|
|
238
|
+
setIsLoading(true);
|
|
239
|
+
const result = await (0, import_browser_sdk2.waitForPhantomExtension)(3e3);
|
|
240
|
+
if (isMounted) {
|
|
241
|
+
setIsInstalled(result);
|
|
242
|
+
}
|
|
243
|
+
} catch (error) {
|
|
244
|
+
if (isMounted) {
|
|
245
|
+
setIsInstalled(false);
|
|
246
|
+
}
|
|
247
|
+
} finally {
|
|
248
|
+
if (isMounted) {
|
|
249
|
+
setIsLoading(false);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
checkExtension();
|
|
254
|
+
return () => {
|
|
255
|
+
isMounted = false;
|
|
256
|
+
};
|
|
257
|
+
}, []);
|
|
258
|
+
return { isLoading, isInstalled };
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// src/hooks/useAutoConfirm.ts
|
|
229
262
|
var import_react4 = require("react");
|
|
230
|
-
function
|
|
231
|
-
const { sdk } = usePhantom();
|
|
232
|
-
const [
|
|
263
|
+
function useAutoConfirm() {
|
|
264
|
+
const { sdk, currentProviderType } = usePhantom();
|
|
265
|
+
const [status, setStatus] = (0, import_react4.useState)(null);
|
|
266
|
+
const [supportedChains, setSupportedChains] = (0, import_react4.useState)(null);
|
|
267
|
+
const [isLoading, setIsLoading] = (0, import_react4.useState)(false);
|
|
233
268
|
const [error, setError] = (0, import_react4.useState)(null);
|
|
234
|
-
const
|
|
269
|
+
const isInjected = currentProviderType === "injected";
|
|
270
|
+
const enable = (0, import_react4.useCallback)(
|
|
235
271
|
async (params) => {
|
|
236
272
|
if (!sdk) {
|
|
237
273
|
throw new Error("SDK not initialized");
|
|
238
274
|
}
|
|
239
|
-
if (!
|
|
240
|
-
throw new Error("
|
|
275
|
+
if (!isInjected) {
|
|
276
|
+
throw new Error("Auto-confirm is only available for injected (extension) providers");
|
|
241
277
|
}
|
|
242
|
-
setIsSigning(true);
|
|
243
|
-
setError(null);
|
|
244
278
|
try {
|
|
245
|
-
|
|
246
|
-
|
|
279
|
+
setIsLoading(true);
|
|
280
|
+
setError(null);
|
|
281
|
+
const result = await sdk.enableAutoConfirm(params);
|
|
282
|
+
setStatus(result);
|
|
283
|
+
return result;
|
|
247
284
|
} catch (err) {
|
|
248
|
-
|
|
249
|
-
|
|
285
|
+
const error2 = err instanceof Error ? err : new Error("Unknown error occurred");
|
|
286
|
+
setError(error2);
|
|
287
|
+
throw error2;
|
|
250
288
|
} finally {
|
|
251
|
-
|
|
289
|
+
setIsLoading(false);
|
|
252
290
|
}
|
|
253
291
|
},
|
|
254
|
-
[sdk]
|
|
292
|
+
[sdk, isInjected]
|
|
255
293
|
);
|
|
294
|
+
const disable = (0, import_react4.useCallback)(async () => {
|
|
295
|
+
if (!sdk) {
|
|
296
|
+
throw new Error("SDK not initialized");
|
|
297
|
+
}
|
|
298
|
+
if (!isInjected) {
|
|
299
|
+
throw new Error("Auto-confirm is only available for injected (extension) providers");
|
|
300
|
+
}
|
|
301
|
+
try {
|
|
302
|
+
setIsLoading(true);
|
|
303
|
+
setError(null);
|
|
304
|
+
await sdk.disableAutoConfirm();
|
|
305
|
+
const newStatus = await sdk.getAutoConfirmStatus();
|
|
306
|
+
setStatus(newStatus);
|
|
307
|
+
} catch (err) {
|
|
308
|
+
const error2 = err instanceof Error ? err : new Error("Unknown error occurred");
|
|
309
|
+
setError(error2);
|
|
310
|
+
throw error2;
|
|
311
|
+
} finally {
|
|
312
|
+
setIsLoading(false);
|
|
313
|
+
}
|
|
314
|
+
}, [sdk, isInjected]);
|
|
315
|
+
const refetch = (0, import_react4.useCallback)(async () => {
|
|
316
|
+
if (!sdk || !isInjected) {
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
try {
|
|
320
|
+
setIsLoading(true);
|
|
321
|
+
setError(null);
|
|
322
|
+
const [statusResult, supportedResult] = await Promise.all([
|
|
323
|
+
sdk.getAutoConfirmStatus(),
|
|
324
|
+
sdk.getSupportedAutoConfirmChains()
|
|
325
|
+
]);
|
|
326
|
+
setStatus(statusResult);
|
|
327
|
+
setSupportedChains(supportedResult);
|
|
328
|
+
} catch (err) {
|
|
329
|
+
const error2 = err instanceof Error ? err : new Error("Failed to fetch auto-confirm data");
|
|
330
|
+
setError(error2);
|
|
331
|
+
} finally {
|
|
332
|
+
setIsLoading(false);
|
|
333
|
+
}
|
|
334
|
+
}, [sdk, isInjected]);
|
|
335
|
+
(0, import_react4.useEffect)(() => {
|
|
336
|
+
if (sdk && isInjected) {
|
|
337
|
+
refetch();
|
|
338
|
+
} else {
|
|
339
|
+
setStatus(null);
|
|
340
|
+
setSupportedChains(null);
|
|
341
|
+
setError(null);
|
|
342
|
+
}
|
|
343
|
+
}, [sdk, isInjected, refetch]);
|
|
256
344
|
return {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
345
|
+
enable,
|
|
346
|
+
disable,
|
|
347
|
+
status,
|
|
348
|
+
supportedChains,
|
|
349
|
+
isLoading,
|
|
350
|
+
error,
|
|
351
|
+
refetch
|
|
260
352
|
};
|
|
261
353
|
}
|
|
262
354
|
|
|
263
|
-
// src/hooks/
|
|
355
|
+
// src/hooks/useSolana.ts
|
|
264
356
|
var import_react5 = require("react");
|
|
265
|
-
function
|
|
266
|
-
const { sdk } = usePhantom();
|
|
267
|
-
const
|
|
268
|
-
|
|
357
|
+
function useSolana() {
|
|
358
|
+
const { sdk, isConnected } = usePhantom();
|
|
359
|
+
const solanaChain = (0, import_react5.useMemo)(() => {
|
|
360
|
+
if (!sdk || !isConnected)
|
|
361
|
+
return null;
|
|
362
|
+
try {
|
|
363
|
+
return sdk.solana;
|
|
364
|
+
} catch {
|
|
365
|
+
return null;
|
|
366
|
+
}
|
|
367
|
+
}, [sdk, isConnected]);
|
|
368
|
+
const signMessage = (0, import_react5.useCallback)(
|
|
369
|
+
async (message) => {
|
|
370
|
+
if (!solanaChain)
|
|
371
|
+
throw new Error("Solana chain not available. Ensure SDK is connected.");
|
|
372
|
+
return solanaChain.signMessage(message);
|
|
373
|
+
},
|
|
374
|
+
[solanaChain]
|
|
375
|
+
);
|
|
376
|
+
const signTransaction = (0, import_react5.useCallback)(
|
|
377
|
+
async (transaction) => {
|
|
378
|
+
if (!solanaChain)
|
|
379
|
+
throw new Error("Solana chain not available. Ensure SDK is connected.");
|
|
380
|
+
return solanaChain.signTransaction(transaction);
|
|
381
|
+
},
|
|
382
|
+
[solanaChain]
|
|
383
|
+
);
|
|
269
384
|
const signAndSendTransaction = (0, import_react5.useCallback)(
|
|
270
|
-
async (
|
|
271
|
-
if (!
|
|
272
|
-
throw new Error("
|
|
273
|
-
|
|
274
|
-
if (!sdk.isConnected()) {
|
|
275
|
-
throw new Error("Wallet not connected");
|
|
276
|
-
}
|
|
277
|
-
setIsSigning(true);
|
|
278
|
-
setError(null);
|
|
279
|
-
try {
|
|
280
|
-
const result = await sdk.signAndSendTransaction(params);
|
|
281
|
-
return result;
|
|
282
|
-
} catch (err) {
|
|
283
|
-
setError(err);
|
|
284
|
-
throw err;
|
|
285
|
-
} finally {
|
|
286
|
-
setIsSigning(false);
|
|
287
|
-
}
|
|
385
|
+
async (transaction) => {
|
|
386
|
+
if (!solanaChain)
|
|
387
|
+
throw new Error("Solana chain not available. Ensure SDK is connected.");
|
|
388
|
+
return solanaChain.signAndSendTransaction(transaction);
|
|
288
389
|
},
|
|
289
|
-
[
|
|
390
|
+
[solanaChain]
|
|
391
|
+
);
|
|
392
|
+
const connect = (0, import_react5.useCallback)(
|
|
393
|
+
async (options) => {
|
|
394
|
+
if (!solanaChain)
|
|
395
|
+
throw new Error("Solana chain not available. Ensure SDK is connected.");
|
|
396
|
+
return solanaChain.connect(options);
|
|
397
|
+
},
|
|
398
|
+
[solanaChain]
|
|
399
|
+
);
|
|
400
|
+
const disconnect = (0, import_react5.useCallback)(async () => {
|
|
401
|
+
if (!solanaChain)
|
|
402
|
+
throw new Error("Solana chain not available. Ensure SDK is connected.");
|
|
403
|
+
return solanaChain.disconnect();
|
|
404
|
+
}, [solanaChain]);
|
|
405
|
+
const switchNetwork = (0, import_react5.useCallback)(
|
|
406
|
+
async (network) => {
|
|
407
|
+
if (!solanaChain)
|
|
408
|
+
throw new Error("Solana chain not available. Ensure SDK is connected.");
|
|
409
|
+
return solanaChain.switchNetwork?.(network);
|
|
410
|
+
},
|
|
411
|
+
[solanaChain]
|
|
290
412
|
);
|
|
413
|
+
const getPublicKey = (0, import_react5.useCallback)(async () => {
|
|
414
|
+
if (!solanaChain)
|
|
415
|
+
return null;
|
|
416
|
+
return solanaChain.getPublicKey();
|
|
417
|
+
}, [solanaChain]);
|
|
291
418
|
return {
|
|
419
|
+
// Chain instance for advanced usage
|
|
420
|
+
solana: solanaChain,
|
|
421
|
+
// Convenient methods
|
|
422
|
+
signMessage,
|
|
423
|
+
signTransaction,
|
|
292
424
|
signAndSendTransaction,
|
|
293
|
-
|
|
294
|
-
|
|
425
|
+
connect,
|
|
426
|
+
disconnect,
|
|
427
|
+
switchNetwork,
|
|
428
|
+
getPublicKey,
|
|
429
|
+
// State
|
|
430
|
+
isAvailable: !!solanaChain,
|
|
431
|
+
isConnected: solanaChain?.isConnected() ?? false
|
|
295
432
|
};
|
|
296
433
|
}
|
|
297
434
|
|
|
298
|
-
// src/hooks/
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
const [isLoading, setIsLoading] = React.useState(cachedIsInstalled === null);
|
|
310
|
-
const [isInstalled, setIsInstalled] = React.useState(cachedIsInstalled ?? false);
|
|
311
|
-
React.useEffect(() => {
|
|
312
|
-
if (!sdk) {
|
|
313
|
-
setIsLoading(false);
|
|
314
|
-
return;
|
|
315
|
-
}
|
|
316
|
-
if (cachedIsInstalled !== null) {
|
|
317
|
-
setIsInstalled(cachedIsInstalled);
|
|
318
|
-
setIsLoading(false);
|
|
319
|
-
return;
|
|
435
|
+
// src/hooks/useEthereum.ts
|
|
436
|
+
var import_react6 = require("react");
|
|
437
|
+
function useEthereum() {
|
|
438
|
+
const { sdk, isConnected } = usePhantom();
|
|
439
|
+
const ethereumChain = (0, import_react6.useMemo)(() => {
|
|
440
|
+
if (!sdk || !isConnected)
|
|
441
|
+
return null;
|
|
442
|
+
try {
|
|
443
|
+
return sdk.ethereum;
|
|
444
|
+
} catch {
|
|
445
|
+
return null;
|
|
320
446
|
}
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
447
|
+
}, [sdk, isConnected]);
|
|
448
|
+
const request = (0, import_react6.useCallback)(
|
|
449
|
+
async (args) => {
|
|
450
|
+
if (!ethereumChain)
|
|
451
|
+
throw new Error("Ethereum chain not available. Ensure SDK is connected.");
|
|
452
|
+
return ethereumChain.request(args);
|
|
453
|
+
},
|
|
454
|
+
[ethereumChain]
|
|
455
|
+
);
|
|
456
|
+
const signPersonalMessage = (0, import_react6.useCallback)(
|
|
457
|
+
async (message, address) => {
|
|
458
|
+
return request({
|
|
459
|
+
method: "personal_sign",
|
|
460
|
+
params: [message, address]
|
|
461
|
+
});
|
|
462
|
+
},
|
|
463
|
+
[request]
|
|
464
|
+
);
|
|
465
|
+
const sendTransaction = (0, import_react6.useCallback)(
|
|
466
|
+
async (transaction) => {
|
|
467
|
+
if (!ethereumChain)
|
|
468
|
+
throw new Error("Ethereum chain not available. Ensure SDK is connected.");
|
|
469
|
+
return ethereumChain.sendTransaction(transaction);
|
|
470
|
+
},
|
|
471
|
+
[ethereumChain]
|
|
472
|
+
);
|
|
473
|
+
const switchChain = (0, import_react6.useCallback)(
|
|
474
|
+
async (chainId) => {
|
|
475
|
+
if (!ethereumChain)
|
|
476
|
+
throw new Error("Ethereum chain not available. Ensure SDK is connected.");
|
|
477
|
+
return ethereumChain.switchChain(chainId);
|
|
478
|
+
},
|
|
479
|
+
[ethereumChain]
|
|
480
|
+
);
|
|
481
|
+
const getChainId = (0, import_react6.useCallback)(async () => {
|
|
482
|
+
if (!ethereumChain)
|
|
483
|
+
throw new Error("Ethereum chain not available. Ensure SDK is connected.");
|
|
484
|
+
return ethereumChain.getChainId();
|
|
485
|
+
}, [ethereumChain]);
|
|
486
|
+
const getAccounts = (0, import_react6.useCallback)(async () => {
|
|
487
|
+
if (!ethereumChain)
|
|
488
|
+
throw new Error("Ethereum chain not available. Ensure SDK is connected.");
|
|
489
|
+
return ethereumChain.getAccounts();
|
|
490
|
+
}, [ethereumChain]);
|
|
491
|
+
const signMessage = (0, import_react6.useCallback)(
|
|
492
|
+
async (message) => {
|
|
493
|
+
return request({
|
|
494
|
+
method: "eth_sign",
|
|
495
|
+
params: [await getAccounts().then((accounts) => accounts[0]), message]
|
|
496
|
+
});
|
|
497
|
+
},
|
|
498
|
+
[request, getAccounts]
|
|
499
|
+
);
|
|
500
|
+
const signTypedData = (0, import_react6.useCallback)(
|
|
501
|
+
async (typedData) => {
|
|
502
|
+
const accounts = await getAccounts();
|
|
503
|
+
return request({
|
|
504
|
+
method: "eth_signTypedData_v4",
|
|
505
|
+
params: [accounts[0], JSON.stringify(typedData)]
|
|
506
|
+
});
|
|
507
|
+
},
|
|
508
|
+
[request, getAccounts]
|
|
509
|
+
);
|
|
510
|
+
return {
|
|
511
|
+
// Chain instance for advanced usage
|
|
512
|
+
ethereum: ethereumChain,
|
|
513
|
+
// Standard EIP-1193 interface
|
|
514
|
+
request,
|
|
515
|
+
// Convenient methods
|
|
516
|
+
signPersonalMessage,
|
|
517
|
+
signMessage,
|
|
518
|
+
signTypedData,
|
|
519
|
+
sendTransaction,
|
|
520
|
+
switchChain,
|
|
521
|
+
getChainId,
|
|
522
|
+
getAccounts,
|
|
523
|
+
// State
|
|
524
|
+
isAvailable: !!ethereumChain,
|
|
525
|
+
isConnected: ethereumChain?.isConnected() ?? false
|
|
526
|
+
};
|
|
337
527
|
}
|
|
338
528
|
|
|
339
529
|
// src/index.ts
|
|
340
|
-
var
|
|
530
|
+
var import_browser_sdk3 = require("@phantom/browser-sdk");
|