@phantom/react-sdk 1.0.0-beta.21 → 1.0.0-beta.22

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.js CHANGED
@@ -30,11 +30,16 @@ 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: () => import_browser_sdk4.AddressType,
34
- DebugLevel: () => import_browser_sdk4.DebugLevel,
35
- NetworkId: () => import_browser_sdk4.NetworkId,
33
+ AddressType: () => import_browser_sdk6.AddressType,
34
+ ConnectButton: () => ConnectButton,
35
+ DebugLevel: () => import_browser_sdk6.DebugLevel,
36
+ NetworkId: () => import_browser_sdk6.NetworkId,
36
37
  PhantomProvider: () => PhantomProvider,
37
- debug: () => import_browser_sdk4.debug,
38
+ darkTheme: () => import_wallet_sdk_ui7.darkTheme,
39
+ debug: () => import_browser_sdk6.debug,
40
+ isMobileDevice: () => import_browser_sdk6.isMobileDevice,
41
+ lightTheme: () => import_wallet_sdk_ui7.lightTheme,
42
+ mergeTheme: () => import_wallet_sdk_ui7.mergeTheme,
38
43
  useAccounts: () => useAccounts,
39
44
  useAutoConfirm: () => useAutoConfirm,
40
45
  useConnect: () => useConnect,
@@ -42,39 +47,498 @@ __export(src_exports, {
42
47
  useEthereum: () => useEthereum,
43
48
  useIsExtensionInstalled: () => useIsExtensionInstalled,
44
49
  useIsPhantomLoginAvailable: () => useIsPhantomLoginAvailable,
50
+ useModal: () => useModal,
45
51
  usePhantom: () => usePhantom,
46
- useSolana: () => useSolana
52
+ useSolana: () => useSolana,
53
+ useTheme: () => import_wallet_sdk_ui5.useTheme
47
54
  });
48
55
  module.exports = __toCommonJS(src_exports);
49
56
 
50
57
  // src/PhantomProvider.tsx
58
+ var import_react8 = require("react");
59
+ var import_browser_sdk5 = require("@phantom/browser-sdk");
60
+ var import_wallet_sdk_ui4 = require("@phantom/wallet-sdk-ui");
61
+
62
+ // src/PhantomContext.ts
51
63
  var import_react = require("react");
64
+ var PhantomContext = (0, import_react.createContext)(void 0);
65
+ function usePhantom() {
66
+ const context = (0, import_react.useContext)(PhantomContext);
67
+ if (!context) {
68
+ throw new Error("usePhantom must be used within a PhantomProvider");
69
+ }
70
+ return context;
71
+ }
72
+
73
+ // src/ModalProvider.tsx
74
+ var import_react7 = require("react");
75
+
76
+ // src/ModalContext.ts
77
+ var import_react2 = require("react");
78
+ var ModalContext = (0, import_react2.createContext)(void 0);
79
+ function useModal() {
80
+ const context = (0, import_react2.useContext)(ModalContext);
81
+ if (!context) {
82
+ throw new Error("useModal must be used within a ModalProvider");
83
+ }
84
+ return {
85
+ open: context.openModal,
86
+ close: context.closeModal,
87
+ isOpened: context.isModalOpen
88
+ };
89
+ }
90
+
91
+ // src/ModalProvider.tsx
92
+ var import_browser_sdk4 = require("@phantom/browser-sdk");
93
+ var import_wallet_sdk_ui3 = require("@phantom/wallet-sdk-ui");
94
+
95
+ // src/components/ConnectModalContent.tsx
96
+ var import_react4 = require("react");
97
+ var import_browser_sdk3 = require("@phantom/browser-sdk");
98
+ var import_wallet_sdk_ui = require("@phantom/wallet-sdk-ui");
99
+
100
+ // src/hooks/useIsExtensionInstalled.ts
101
+ var React = __toESM(require("react"));
52
102
  var import_browser_sdk = require("@phantom/browser-sdk");
103
+ function useIsExtensionInstalled() {
104
+ const [isLoading, setIsLoading] = React.useState(true);
105
+ const [isInstalled, setIsInstalled] = React.useState(false);
106
+ React.useEffect(() => {
107
+ let isMounted = true;
108
+ const checkExtension = async () => {
109
+ try {
110
+ setIsLoading(true);
111
+ const result = await (0, import_browser_sdk.waitForPhantomExtension)(3e3);
112
+ if (isMounted) {
113
+ setIsInstalled(result);
114
+ }
115
+ } catch (error) {
116
+ if (isMounted) {
117
+ setIsInstalled(false);
118
+ }
119
+ } finally {
120
+ if (isMounted) {
121
+ setIsLoading(false);
122
+ }
123
+ }
124
+ };
125
+ checkExtension();
126
+ return () => {
127
+ isMounted = false;
128
+ };
129
+ }, []);
130
+ return { isLoading, isInstalled };
131
+ }
132
+
133
+ // src/hooks/useIsPhantomLoginAvailable.ts
134
+ var React2 = __toESM(require("react"));
135
+ var import_browser_sdk2 = require("@phantom/browser-sdk");
136
+ function useIsPhantomLoginAvailable() {
137
+ const [isLoading, setIsLoading] = React2.useState(true);
138
+ const [isAvailable, setIsAvailable] = React2.useState(false);
139
+ React2.useEffect(() => {
140
+ let isMounted = true;
141
+ const checkPhantomLogin = async () => {
142
+ try {
143
+ setIsLoading(true);
144
+ const result = await (0, import_browser_sdk2.isPhantomLoginAvailable)(3e3);
145
+ if (isMounted) {
146
+ setIsAvailable(result);
147
+ }
148
+ } catch (error) {
149
+ if (isMounted) {
150
+ setIsAvailable(false);
151
+ }
152
+ } finally {
153
+ if (isMounted) {
154
+ setIsLoading(false);
155
+ }
156
+ }
157
+ };
158
+ checkPhantomLogin();
159
+ return () => {
160
+ isMounted = false;
161
+ };
162
+ }, []);
163
+ return { isLoading, isAvailable };
164
+ }
165
+
166
+ // src/hooks/useConnect.ts
167
+ var import_react3 = require("react");
168
+ function useConnect() {
169
+ const { sdk, isConnecting, isLoading, connectError } = usePhantom();
170
+ const connect = (0, import_react3.useCallback)(
171
+ async (options) => {
172
+ if (!sdk) {
173
+ throw new Error("SDK not initialized");
174
+ }
175
+ try {
176
+ const result = await sdk.connect(options);
177
+ return result;
178
+ } catch (err) {
179
+ console.error("Error connecting to Phantom:", err);
180
+ throw err;
181
+ }
182
+ },
183
+ [sdk]
184
+ );
185
+ return {
186
+ connect,
187
+ isConnecting,
188
+ isLoading,
189
+ error: connectError
190
+ };
191
+ }
192
+
193
+ // src/components/ConnectModalContent.tsx
53
194
  var import_jsx_runtime = require("react/jsx-runtime");
54
- var PhantomContext = (0, import_react.createContext)(void 0);
55
- function PhantomProvider({ children, config, debugConfig }) {
56
- const memoizedConfig = (0, import_react.useMemo)(() => config, [config]);
57
- const [sdk, setSdk] = (0, import_react.useState)(null);
58
- const [isClient, setIsClient] = (0, import_react.useState)(false);
59
- const [isConnected, setIsConnected] = (0, import_react.useState)(false);
60
- const [isConnecting, setIsConnecting] = (0, import_react.useState)(false);
61
- const [connectError, setConnectError] = (0, import_react.useState)(null);
62
- const [addresses, setAddresses] = (0, import_react.useState)([]);
63
- const [currentProviderType, setCurrentProviderType] = (0, import_react.useState)(
64
- memoizedConfig.providerType || null
195
+ function ConnectModalContent({ appIcon, appName = "App Name", onClose }) {
196
+ const theme = (0, import_wallet_sdk_ui.useTheme)();
197
+ const { isLoading, allowedProviders } = usePhantom();
198
+ const baseConnect = useConnect();
199
+ const isExtensionInstalled = useIsExtensionInstalled();
200
+ const isPhantomLoginAvailable2 = useIsPhantomLoginAvailable();
201
+ const isMobile = (0, import_react4.useMemo)(() => (0, import_browser_sdk3.isMobileDevice)(), []);
202
+ const [isConnecting, setIsConnecting] = (0, import_react4.useState)(false);
203
+ const [error, setError] = (0, import_react4.useState)(null);
204
+ const [providerType, setProviderType] = (0, import_react4.useState)(null);
205
+ const showDivider = !(allowedProviders.length === 1 && allowedProviders.includes("injected"));
206
+ const connectWithAuthProvider = (0, import_react4.useCallback)(
207
+ async (provider) => {
208
+ try {
209
+ setIsConnecting(true);
210
+ setError(null);
211
+ setProviderType(provider);
212
+ await baseConnect.connect({ provider });
213
+ onClose();
214
+ } catch (err) {
215
+ const error2 = err instanceof Error ? err : new Error(String(err));
216
+ setError(error2);
217
+ } finally {
218
+ setIsConnecting(false);
219
+ setProviderType(null);
220
+ }
221
+ },
222
+ [baseConnect, onClose]
223
+ );
224
+ const connectWithDeeplink = (0, import_react4.useCallback)(() => {
225
+ try {
226
+ setIsConnecting(true);
227
+ setError(null);
228
+ setProviderType("deeplink");
229
+ const deeplinkUrl = (0, import_browser_sdk3.getDeeplinkToPhantom)();
230
+ window.location.href = deeplinkUrl;
231
+ onClose();
232
+ } catch (err) {
233
+ const error2 = err instanceof Error ? err : new Error(String(err));
234
+ setError(error2);
235
+ } finally {
236
+ setIsConnecting(false);
237
+ setProviderType(null);
238
+ }
239
+ }, [onClose]);
240
+ const appIconStyle = {
241
+ width: "56px",
242
+ height: "56px",
243
+ borderRadius: "50%",
244
+ display: "block",
245
+ objectFit: "cover"
246
+ };
247
+ const buttonContainerStyle = {
248
+ display: "flex",
249
+ flexDirection: "column",
250
+ alignItems: "center",
251
+ gap: "12px",
252
+ width: "100%"
253
+ };
254
+ const socialButtonRowStyle = {
255
+ display: "flex",
256
+ gap: "12px",
257
+ width: "100%"
258
+ };
259
+ const dividerStyle = {
260
+ display: "flex",
261
+ alignItems: "center",
262
+ width: "100%",
263
+ margin: "24px 0",
264
+ ...theme.typography.caption,
265
+ color: theme.secondary,
266
+ textTransform: "uppercase"
267
+ };
268
+ const dividerLineStyle = {
269
+ flex: 1,
270
+ height: "1px",
271
+ backgroundColor: (0, import_wallet_sdk_ui.hexToRgba)(theme.secondary, 0.1)
272
+ };
273
+ const dividerTextStyle = {
274
+ padding: "0 12px"
275
+ };
276
+ const errorStyle = {
277
+ backgroundColor: "rgba(220, 53, 69, 0.1)",
278
+ color: "#ff6b6b",
279
+ border: "1px solid rgba(220, 53, 69, 0.3)",
280
+ borderRadius: theme.borderRadius,
281
+ padding: "12px",
282
+ width: "100%",
283
+ fontSize: "14px"
284
+ };
285
+ const loadingContainerStyle = {
286
+ display: "flex",
287
+ flexDirection: "column",
288
+ alignItems: "center",
289
+ justifyContent: "center",
290
+ padding: "24px",
291
+ gap: "12px"
292
+ };
293
+ const spinnerStyle = {
294
+ width: "40px",
295
+ height: "40px",
296
+ border: `3px solid ${theme.secondary}`,
297
+ borderTop: `3px solid ${theme.brand}`,
298
+ borderRadius: "50%",
299
+ animation: "spin 1s linear infinite"
300
+ };
301
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
302
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: `
303
+ @keyframes spin {
304
+ 0% { transform: rotate(0deg); }
305
+ 100% { transform: rotate(360deg); }
306
+ }
307
+ ` }),
308
+ appIcon && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", { src: appIcon, alt: appName, style: appIconStyle }),
309
+ error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: errorStyle, children: error.message }),
310
+ isLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: loadingContainerStyle, children: [
311
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: spinnerStyle }),
312
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_wallet_sdk_ui.Text, { variant: "label", color: theme.secondary, children: "Loading..." })
313
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: buttonContainerStyle, children: [
314
+ isMobile && !isExtensionInstalled.isInstalled && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
315
+ import_wallet_sdk_ui.Button,
316
+ {
317
+ onClick: connectWithDeeplink,
318
+ disabled: isConnecting,
319
+ isLoading: isConnecting && providerType === "deeplink",
320
+ fullWidth: true,
321
+ children: isConnecting && providerType === "deeplink" ? "Opening Phantom..." : "Open in Phantom App"
322
+ }
323
+ ),
324
+ !isMobile && allowedProviders.includes("phantom") && isPhantomLoginAvailable2.isAvailable && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
325
+ import_wallet_sdk_ui.LoginWithPhantomButton,
326
+ {
327
+ onClick: () => connectWithAuthProvider("phantom"),
328
+ disabled: isConnecting,
329
+ isLoading: isConnecting && providerType === "phantom"
330
+ }
331
+ ),
332
+ (allowedProviders.includes("google") || allowedProviders.includes("apple")) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: socialButtonRowStyle, children: [
333
+ allowedProviders.includes("google") && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
334
+ import_wallet_sdk_ui.Button,
335
+ {
336
+ onClick: () => connectWithAuthProvider("google"),
337
+ disabled: isConnecting,
338
+ isLoading: isConnecting && providerType === "google",
339
+ fullWidth: true,
340
+ centered: allowedProviders.includes("apple"),
341
+ children: [
342
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_wallet_sdk_ui.Icon, { type: "google", size: 20 }),
343
+ !allowedProviders.includes("apple") && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_wallet_sdk_ui.Text, { variant: "captionBold", children: "Continue with Google" })
344
+ ]
345
+ }
346
+ ),
347
+ allowedProviders.includes("apple") && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
348
+ import_wallet_sdk_ui.Button,
349
+ {
350
+ onClick: () => connectWithAuthProvider("apple"),
351
+ disabled: isConnecting,
352
+ isLoading: isConnecting && providerType === "apple",
353
+ fullWidth: true,
354
+ centered: allowedProviders.includes("google"),
355
+ children: [
356
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_wallet_sdk_ui.Icon, { type: "apple", size: 20 }),
357
+ !allowedProviders.includes("google") && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_wallet_sdk_ui.Text, { variant: "captionBold", children: "Continue with Apple" })
358
+ ]
359
+ }
360
+ )
361
+ ] }),
362
+ !isMobile && allowedProviders.includes("injected") && isExtensionInstalled.isInstalled && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
363
+ showDivider && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: dividerStyle, children: [
364
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: dividerLineStyle }),
365
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: dividerTextStyle, children: "OR" }),
366
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: dividerLineStyle })
367
+ ] }),
368
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
369
+ import_wallet_sdk_ui.Button,
370
+ {
371
+ onClick: () => connectWithAuthProvider("injected"),
372
+ disabled: isConnecting,
373
+ isLoading: isConnecting && providerType === "injected",
374
+ fullWidth: true,
375
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: "8px" }, children: [
376
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
377
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_wallet_sdk_ui.BoundedIcon, { type: "phantom", size: 20, background: "#AB9FF2", color: "white" }),
378
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_wallet_sdk_ui.Text, { variant: "captionBold", children: "Phantom" })
379
+ ] }),
380
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
381
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_wallet_sdk_ui.Text, { variant: "label", color: theme.secondary, children: "Detected" }),
382
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_wallet_sdk_ui.Icon, { type: "chevron-right", size: 16 })
383
+ ] })
384
+ ] })
385
+ }
386
+ )
387
+ ] })
388
+ ] })
389
+ ] });
390
+ }
391
+
392
+ // src/components/ConnectedModalContent.tsx
393
+ var import_react6 = require("react");
394
+ var import_wallet_sdk_ui2 = require("@phantom/wallet-sdk-ui");
395
+
396
+ // src/hooks/useDisconnect.ts
397
+ var import_react5 = require("react");
398
+ function useDisconnect() {
399
+ const { sdk } = usePhantom();
400
+ const [isDisconnecting, setIsDisconnecting] = (0, import_react5.useState)(false);
401
+ const [error, setError] = (0, import_react5.useState)(null);
402
+ const disconnect = (0, import_react5.useCallback)(async () => {
403
+ if (!sdk) {
404
+ throw new Error("SDK not initialized");
405
+ }
406
+ setIsDisconnecting(true);
407
+ setError(null);
408
+ try {
409
+ await sdk.disconnect();
410
+ } catch (err) {
411
+ const error2 = err instanceof Error ? err : new Error(String(err));
412
+ setError(error2);
413
+ throw err;
414
+ } finally {
415
+ setIsDisconnecting(false);
416
+ }
417
+ }, [sdk]);
418
+ return {
419
+ disconnect,
420
+ isDisconnecting,
421
+ error
422
+ };
423
+ }
424
+
425
+ // src/components/ConnectedModalContent.tsx
426
+ var import_jsx_runtime2 = require("react/jsx-runtime");
427
+ function ConnectedModalContent({ onClose }) {
428
+ const theme = (0, import_wallet_sdk_ui2.useTheme)();
429
+ const { addresses } = usePhantom();
430
+ const { disconnect } = useDisconnect();
431
+ const [isDisconnecting, setIsDisconnecting] = (0, import_react6.useState)(false);
432
+ const [disconnectError, setDisconnectError] = (0, import_react6.useState)(null);
433
+ (0, import_react6.useEffect)(() => {
434
+ setDisconnectError(null);
435
+ }, []);
436
+ const handleDisconnect = async () => {
437
+ try {
438
+ setIsDisconnecting(true);
439
+ setDisconnectError(null);
440
+ await disconnect();
441
+ onClose();
442
+ } catch (err) {
443
+ const error = err instanceof Error ? err : new Error(String(err));
444
+ setDisconnectError(error);
445
+ } finally {
446
+ setIsDisconnecting(false);
447
+ }
448
+ };
449
+ const accountListStyle = {
450
+ display: "flex",
451
+ flexDirection: "column",
452
+ gap: "16px",
453
+ width: "100%"
454
+ };
455
+ const accountItemStyle = {
456
+ display: "flex",
457
+ flexDirection: "column",
458
+ gap: "8px",
459
+ width: "100%"
460
+ };
461
+ const addressTextStyle = {
462
+ fontFamily: "monospace",
463
+ wordBreak: "break-all"
464
+ };
465
+ const errorContainerStyle = {
466
+ padding: "12px",
467
+ backgroundColor: "rgba(220, 53, 69, 0.1)",
468
+ borderRadius: theme.borderRadius,
469
+ border: "1px solid rgba(220, 53, 69, 0.3)",
470
+ width: "100%"
471
+ };
472
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
473
+ addresses && addresses.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: accountListStyle, children: addresses.map((account, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: accountItemStyle, children: [
474
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_wallet_sdk_ui2.Text, { variant: "label", color: theme.secondary, style: { textTransform: "uppercase" }, children: account.addressType }),
475
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: addressTextStyle, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_wallet_sdk_ui2.Text, { variant: "caption", children: account.address }) })
476
+ ] }, index)) }),
477
+ disconnectError && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: errorContainerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_wallet_sdk_ui2.Text, { variant: "caption", color: theme.error, children: "Failed to disconnect" }) }),
478
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_wallet_sdk_ui2.Button, { onClick: handleDisconnect, disabled: isDisconnecting, isLoading: isDisconnecting, fullWidth: true, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_wallet_sdk_ui2.Text, { variant: "captionBold", children: isDisconnecting ? "Disconnecting..." : "Disconnect" }) })
479
+ ] });
480
+ }
481
+
482
+ // src/ModalProvider.tsx
483
+ var import_jsx_runtime3 = require("react/jsx-runtime");
484
+ function ModalProvider({ children, appIcon, appName }) {
485
+ const { isConnected } = usePhantom();
486
+ const [isModalOpen, setIsModalOpen] = (0, import_react7.useState)(false);
487
+ const isMobile = (0, import_react7.useMemo)(() => (0, import_browser_sdk4.isMobileDevice)(), []);
488
+ const openModal = (0, import_react7.useCallback)(() => {
489
+ setIsModalOpen(true);
490
+ }, []);
491
+ const closeModal = (0, import_react7.useCallback)(() => {
492
+ setIsModalOpen(false);
493
+ }, []);
494
+ const modalContextValue = (0, import_react7.useMemo)(
495
+ () => ({
496
+ isModalOpen,
497
+ openModal,
498
+ closeModal
499
+ }),
500
+ [isModalOpen, openModal, closeModal]
65
501
  );
66
- const [isPhantomAvailable, setIsPhantomAvailable] = (0, import_react.useState)(false);
67
- const [user, setUser] = (0, import_react.useState)(null);
68
- (0, import_react.useEffect)(() => {
502
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(ModalContext.Provider, { value: modalContextValue, children: [
503
+ children,
504
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
505
+ import_wallet_sdk_ui3.Modal,
506
+ {
507
+ isVisible: isModalOpen,
508
+ onClose: closeModal,
509
+ appIcon,
510
+ appName,
511
+ isConnected,
512
+ isMobile,
513
+ children: isConnected ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ConnectedModalContent, { onClose: closeModal }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ConnectModalContent, { appIcon, appName, onClose: closeModal })
514
+ }
515
+ )
516
+ ] });
517
+ }
518
+
519
+ // src/PhantomProvider.tsx
520
+ var import_jsx_runtime4 = require("react/jsx-runtime");
521
+ function PhantomProvider({ children, config, debugConfig, theme, appIcon, appName }) {
522
+ const memoizedConfig = (0, import_react8.useMemo)(() => config, [config]);
523
+ const resolvedTheme = (0, import_react8.useMemo)(() => (0, import_wallet_sdk_ui4.mergeTheme)(theme || import_wallet_sdk_ui4.darkTheme), [theme]);
524
+ const [sdk, setSdk] = (0, import_react8.useState)(null);
525
+ const [isClient, setIsClient] = (0, import_react8.useState)(false);
526
+ const [isConnected, setIsConnected] = (0, import_react8.useState)(false);
527
+ const [isConnecting, setIsConnecting] = (0, import_react8.useState)(false);
528
+ const [isLoading, setIsLoading] = (0, import_react8.useState)(true);
529
+ const [connectError, setConnectError] = (0, import_react8.useState)(null);
530
+ const [addresses, setAddresses] = (0, import_react8.useState)([]);
531
+ const [user, setUser] = (0, import_react8.useState)(null);
532
+ (0, import_react8.useEffect)(() => {
69
533
  setIsClient(true);
70
534
  }, []);
71
- (0, import_react.useEffect)(() => {
535
+ (0, import_react8.useEffect)(() => {
72
536
  if (!isClient)
73
537
  return;
74
- const sdkInstance = new import_browser_sdk.BrowserSDK(memoizedConfig);
538
+ const sdkInstance = new import_browser_sdk5.BrowserSDK(memoizedConfig);
75
539
  setSdk(sdkInstance);
76
540
  }, [isClient, memoizedConfig]);
77
- (0, import_react.useEffect)(() => {
541
+ (0, import_react8.useEffect)(() => {
78
542
  if (!sdk)
79
543
  return;
80
544
  const handleConnectStart = () => {
@@ -86,7 +550,6 @@ function PhantomProvider({ children, config, debugConfig }) {
86
550
  setIsConnected(true);
87
551
  setIsConnecting(false);
88
552
  setUser(data);
89
- setCurrentProviderType(data.providerType || null);
90
553
  const addrs = await sdk.getAddresses();
91
554
  setAddresses(addrs);
92
555
  } catch (err) {
@@ -122,107 +585,51 @@ function PhantomProvider({ children, config, debugConfig }) {
122
585
  sdk.off("disconnect", handleDisconnect);
123
586
  };
124
587
  }, [sdk]);
125
- (0, import_react.useEffect)(() => {
588
+ (0, import_react8.useEffect)(() => {
126
589
  if (!debugConfig || !sdk)
127
590
  return;
128
591
  sdk.configureDebug(debugConfig);
129
592
  }, [sdk, debugConfig]);
130
- (0, import_react.useEffect)(() => {
593
+ (0, import_react8.useEffect)(() => {
131
594
  if (!isClient || !sdk)
132
595
  return;
133
596
  const initialize = async () => {
134
597
  try {
135
- const available = await import_browser_sdk.BrowserSDK.isPhantomInstalled();
136
- setIsPhantomAvailable(available);
137
- } catch (err) {
138
- console.error("Error checking Phantom extension:", err);
139
- setIsPhantomAvailable(false);
140
- }
141
- if (memoizedConfig.autoConnect !== false) {
142
- sdk.autoConnect().catch(() => {
143
- });
598
+ await sdk.autoConnect();
599
+ } catch (error) {
600
+ console.error("Auto-connect error:", error);
144
601
  }
602
+ setIsLoading(false);
145
603
  };
146
604
  initialize();
147
- }, [sdk, memoizedConfig.autoConnect, isClient]);
148
- const value = (0, import_react.useMemo)(
605
+ }, [sdk, isClient]);
606
+ const value = (0, import_react8.useMemo)(
149
607
  () => ({
150
608
  sdk,
151
609
  isConnected,
152
610
  isConnecting,
611
+ isLoading,
153
612
  connectError,
154
613
  addresses,
155
- currentProviderType,
156
- isPhantomAvailable,
157
614
  isClient,
158
- user
615
+ user,
616
+ theme: resolvedTheme,
617
+ allowedProviders: memoizedConfig.providers
159
618
  }),
160
- [sdk, isConnected, isConnecting, connectError, addresses, currentProviderType, isPhantomAvailable, isClient, user]
161
- );
162
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PhantomContext.Provider, { value, children });
163
- }
164
- function usePhantom() {
165
- const context = (0, import_react.useContext)(PhantomContext);
166
- if (!context) {
167
- throw new Error("usePhantom must be used within a PhantomProvider");
168
- }
169
- return context;
170
- }
171
-
172
- // src/hooks/useConnect.ts
173
- var import_react2 = require("react");
174
- function useConnect() {
175
- const { sdk, isConnecting, connectError, currentProviderType, isPhantomAvailable } = usePhantom();
176
- const connect = (0, import_react2.useCallback)(
177
- async (options) => {
178
- if (!sdk) {
179
- throw new Error("SDK not initialized");
180
- }
181
- try {
182
- const result = await sdk.connect(options);
183
- return result;
184
- } catch (err) {
185
- console.error("Error connecting to Phantom:", err);
186
- throw err;
187
- }
188
- },
189
- [sdk]
619
+ [
620
+ sdk,
621
+ isConnected,
622
+ isConnecting,
623
+ isLoading,
624
+ connectError,
625
+ addresses,
626
+ isClient,
627
+ user,
628
+ resolvedTheme,
629
+ memoizedConfig.providers
630
+ ]
190
631
  );
191
- return {
192
- connect,
193
- isConnecting,
194
- error: connectError,
195
- currentProviderType,
196
- isPhantomAvailable
197
- };
198
- }
199
-
200
- // src/hooks/useDisconnect.ts
201
- var import_react3 = require("react");
202
- function useDisconnect() {
203
- const { sdk } = usePhantom();
204
- const [isDisconnecting, setIsDisconnecting] = (0, import_react3.useState)(false);
205
- const [error, setError] = (0, import_react3.useState)(null);
206
- const disconnect = (0, import_react3.useCallback)(async () => {
207
- if (!sdk) {
208
- throw new Error("SDK not initialized");
209
- }
210
- setIsDisconnecting(true);
211
- setError(null);
212
- try {
213
- await sdk.disconnect();
214
- } catch (err) {
215
- setError(err);
216
- throw err;
217
- } finally {
218
- setIsDisconnecting(false);
219
- }
220
- }, [sdk]);
221
- return {
222
- disconnect,
223
- isDisconnecting,
224
- error
225
- };
632
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_wallet_sdk_ui4.ThemeProvider, { theme: resolvedTheme, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PhantomContext.Provider, { value, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ModalProvider, { appIcon, appName, children }) }) });
226
633
  }
227
634
 
228
635
  // src/hooks/useAccounts.ts
@@ -231,82 +638,16 @@ function useAccounts() {
231
638
  return isConnected ? addresses : null;
232
639
  }
233
640
 
234
- // src/hooks/useIsExtensionInstalled.ts
235
- var React = __toESM(require("react"));
236
- var import_browser_sdk2 = require("@phantom/browser-sdk");
237
- function useIsExtensionInstalled() {
238
- const [isLoading, setIsLoading] = React.useState(true);
239
- const [isInstalled, setIsInstalled] = React.useState(false);
240
- React.useEffect(() => {
241
- let isMounted = true;
242
- const checkExtension = async () => {
243
- try {
244
- setIsLoading(true);
245
- const result = await (0, import_browser_sdk2.waitForPhantomExtension)(3e3);
246
- if (isMounted) {
247
- setIsInstalled(result);
248
- }
249
- } catch (error) {
250
- if (isMounted) {
251
- setIsInstalled(false);
252
- }
253
- } finally {
254
- if (isMounted) {
255
- setIsLoading(false);
256
- }
257
- }
258
- };
259
- checkExtension();
260
- return () => {
261
- isMounted = false;
262
- };
263
- }, []);
264
- return { isLoading, isInstalled };
265
- }
266
-
267
- // src/hooks/useIsPhantomLoginAvailable.ts
268
- var React2 = __toESM(require("react"));
269
- var import_browser_sdk3 = require("@phantom/browser-sdk");
270
- function useIsPhantomLoginAvailable() {
271
- const [isLoading, setIsLoading] = React2.useState(true);
272
- const [isAvailable, setIsAvailable] = React2.useState(false);
273
- React2.useEffect(() => {
274
- let isMounted = true;
275
- const checkPhantomLogin = async () => {
276
- try {
277
- setIsLoading(true);
278
- const result = await (0, import_browser_sdk3.isPhantomLoginAvailable)(3e3);
279
- if (isMounted) {
280
- setIsAvailable(result);
281
- }
282
- } catch (error) {
283
- if (isMounted) {
284
- setIsAvailable(false);
285
- }
286
- } finally {
287
- if (isMounted) {
288
- setIsLoading(false);
289
- }
290
- }
291
- };
292
- checkPhantomLogin();
293
- return () => {
294
- isMounted = false;
295
- };
296
- }, []);
297
- return { isLoading, isAvailable };
298
- }
299
-
300
641
  // src/hooks/useAutoConfirm.ts
301
- var import_react4 = require("react");
642
+ var import_react9 = require("react");
302
643
  function useAutoConfirm() {
303
- const { sdk, currentProviderType } = usePhantom();
304
- const [status, setStatus] = (0, import_react4.useState)(null);
305
- const [supportedChains, setSupportedChains] = (0, import_react4.useState)(null);
306
- const [isLoading, setIsLoading] = (0, import_react4.useState)(false);
307
- const [error, setError] = (0, import_react4.useState)(null);
308
- const isInjected = currentProviderType === "injected";
309
- const enable = (0, import_react4.useCallback)(
644
+ const { sdk, user } = usePhantom();
645
+ const [status, setStatus] = (0, import_react9.useState)(null);
646
+ const [supportedChains, setSupportedChains] = (0, import_react9.useState)(null);
647
+ const [isLoading, setIsLoading] = (0, import_react9.useState)(false);
648
+ const [error, setError] = (0, import_react9.useState)(null);
649
+ const isInjected = user?.authProvider === "injected";
650
+ const enable = (0, import_react9.useCallback)(
310
651
  async (params) => {
311
652
  if (!sdk) {
312
653
  throw new Error("SDK not initialized");
@@ -330,7 +671,7 @@ function useAutoConfirm() {
330
671
  },
331
672
  [sdk, isInjected]
332
673
  );
333
- const disable = (0, import_react4.useCallback)(async () => {
674
+ const disable = (0, import_react9.useCallback)(async () => {
334
675
  if (!sdk) {
335
676
  throw new Error("SDK not initialized");
336
677
  }
@@ -351,7 +692,7 @@ function useAutoConfirm() {
351
692
  setIsLoading(false);
352
693
  }
353
694
  }, [sdk, isInjected]);
354
- const refetch = (0, import_react4.useCallback)(async () => {
695
+ const refetch = (0, import_react9.useCallback)(async () => {
355
696
  if (!sdk || !isInjected) {
356
697
  return;
357
698
  }
@@ -371,7 +712,7 @@ function useAutoConfirm() {
371
712
  setIsLoading(false);
372
713
  }
373
714
  }, [sdk, isInjected]);
374
- (0, import_react4.useEffect)(() => {
715
+ (0, import_react9.useEffect)(() => {
375
716
  if (sdk && isInjected) {
376
717
  refetch();
377
718
  } else {
@@ -427,5 +768,64 @@ function useEthereum() {
427
768
  };
428
769
  }
429
770
 
771
+ // src/hooks/index.ts
772
+ var import_wallet_sdk_ui5 = require("@phantom/wallet-sdk-ui");
773
+
774
+ // src/components/ConnectButton.tsx
775
+ var import_react10 = require("react");
776
+ var import_wallet_sdk_ui6 = require("@phantom/wallet-sdk-ui");
777
+ var import_jsx_runtime5 = require("react/jsx-runtime");
778
+ function ConnectButton({ addressType, fullWidth = false }) {
779
+ const theme = (0, import_wallet_sdk_ui6.useTheme)();
780
+ const { open } = useModal();
781
+ const { isConnected, addresses } = usePhantom();
782
+ const displayAddress = (0, import_react10.useMemo)(() => {
783
+ if (!addresses || addresses.length === 0)
784
+ return null;
785
+ if (addressType) {
786
+ return addresses.find((addr) => addr.addressType === addressType);
787
+ }
788
+ return addresses[0];
789
+ }, [addresses, addressType]);
790
+ const truncatedAddress = (0, import_react10.useMemo)(() => {
791
+ if (!displayAddress)
792
+ return "";
793
+ const addr = displayAddress.address;
794
+ if (addr.length <= 12)
795
+ return addr;
796
+ return `${addr.slice(0, 6)}...${addr.slice(-4)}`;
797
+ }, [displayAddress]);
798
+ const buttonStyle = {
799
+ width: fullWidth ? "100%" : "auto",
800
+ padding: "12px 16px",
801
+ border: "none",
802
+ borderRadius: theme.borderRadius,
803
+ fontFamily: theme.typography.captionBold.fontFamily,
804
+ fontSize: theme.typography.captionBold.fontSize,
805
+ fontStyle: theme.typography.captionBold.fontStyle,
806
+ fontWeight: theme.typography.captionBold.fontWeight,
807
+ lineHeight: theme.typography.captionBold.lineHeight,
808
+ letterSpacing: theme.typography.captionBold.letterSpacing,
809
+ cursor: "pointer",
810
+ transition: "background-color 0.2s",
811
+ display: "flex",
812
+ alignItems: "center",
813
+ justifyContent: "center",
814
+ gap: "8px",
815
+ background: theme.aux,
816
+ color: theme.text
817
+ };
818
+ const connectedButtonStyle = {
819
+ ...buttonStyle,
820
+ background: theme.aux,
821
+ cursor: "pointer"
822
+ };
823
+ if (isConnected && displayAddress) {
824
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { style: connectedButtonStyle, onClick: open, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: { fontFamily: "monospace" }, children: truncatedAddress }) });
825
+ }
826
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { style: buttonStyle, onClick: open, children: "Connect Wallet" });
827
+ }
828
+
430
829
  // src/index.ts
431
- var import_browser_sdk4 = require("@phantom/browser-sdk");
830
+ var import_wallet_sdk_ui7 = require("@phantom/wallet-sdk-ui");
831
+ var import_browser_sdk6 = require("@phantom/browser-sdk");