@phantom/react-sdk 1.0.0-beta.9 → 1.0.2

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,65 +30,819 @@ 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_sdk3.AddressType,
34
- DebugLevel: () => import_browser_sdk3.DebugLevel,
35
- NetworkId: () => import_browser_sdk3.NetworkId,
33
+ AddressType: () => import_browser_sdk8.AddressType,
34
+ ConnectBox: () => ConnectBox,
35
+ ConnectButton: () => ConnectButton,
36
+ DebugLevel: () => import_browser_sdk8.DebugLevel,
37
+ NetworkId: () => import_browser_sdk8.NetworkId,
36
38
  PhantomProvider: () => PhantomProvider,
37
- debug: () => import_browser_sdk3.debug,
39
+ darkTheme: () => import_wallet_sdk_ui10.darkTheme,
40
+ debug: () => import_browser_sdk8.debug,
41
+ isMobileDevice: () => import_browser_sdk8.isMobileDevice,
42
+ lightTheme: () => import_wallet_sdk_ui10.lightTheme,
43
+ mergeTheme: () => import_wallet_sdk_ui10.mergeTheme,
38
44
  useAccounts: () => useAccounts,
39
45
  useAutoConfirm: () => useAutoConfirm,
40
46
  useConnect: () => useConnect,
41
47
  useDisconnect: () => useDisconnect,
48
+ useDiscoveredWallets: () => useDiscoveredWallets,
42
49
  useEthereum: () => useEthereum,
43
50
  useIsExtensionInstalled: () => useIsExtensionInstalled,
51
+ useIsPhantomLoginAvailable: () => useIsPhantomLoginAvailable,
52
+ useModal: () => useModal,
44
53
  usePhantom: () => usePhantom,
45
- useSolana: () => useSolana
54
+ useSolana: () => useSolana,
55
+ useTheme: () => import_wallet_sdk_ui7.useTheme
46
56
  });
47
57
  module.exports = __toCommonJS(src_exports);
48
58
 
49
59
  // src/PhantomProvider.tsx
60
+ var import_react9 = require("react");
61
+ var import_browser_sdk5 = require("@phantom/browser-sdk");
62
+ var import_wallet_sdk_ui6 = require("@phantom/wallet-sdk-ui");
63
+
64
+ // src/PhantomContext.ts
50
65
  var import_react = require("react");
66
+ var PhantomContext = (0, import_react.createContext)(void 0);
67
+ function usePhantom() {
68
+ const context = (0, import_react.useContext)(PhantomContext);
69
+ if (!context) {
70
+ throw new Error("usePhantom must be used within a PhantomProvider");
71
+ }
72
+ return context;
73
+ }
74
+
75
+ // src/ModalProvider.tsx
76
+ var import_react8 = require("react");
77
+
78
+ // src/ModalContext.ts
79
+ var import_react2 = require("react");
80
+ var ModalContext = (0, import_react2.createContext)(void 0);
81
+ function useModal() {
82
+ const context = (0, import_react2.useContext)(ModalContext);
83
+ if (!context) {
84
+ throw new Error("useModal must be used within a ModalProvider");
85
+ }
86
+ return {
87
+ open: context.openModal,
88
+ close: context.closeModal,
89
+ isOpened: context.isModalOpen
90
+ };
91
+ }
92
+
93
+ // src/ModalProvider.tsx
94
+ var import_browser_sdk4 = require("@phantom/browser-sdk");
95
+ var import_wallet_sdk_ui5 = require("@phantom/wallet-sdk-ui");
96
+
97
+ // src/components/ConnectModalContent.tsx
98
+ var import_react5 = require("react");
99
+ var import_browser_sdk3 = require("@phantom/browser-sdk");
100
+ var import_wallet_sdk_ui2 = require("@phantom/wallet-sdk-ui");
101
+ var import_constants = require("@phantom/constants");
102
+
103
+ // src/hooks/useIsExtensionInstalled.ts
104
+ var React = __toESM(require("react"));
51
105
  var import_browser_sdk = require("@phantom/browser-sdk");
106
+ function useIsExtensionInstalled() {
107
+ const [isLoading, setIsLoading] = React.useState(true);
108
+ const [isInstalled, setIsInstalled] = React.useState(false);
109
+ React.useEffect(() => {
110
+ let isMounted = true;
111
+ const checkExtension = async () => {
112
+ try {
113
+ setIsLoading(true);
114
+ const result = await (0, import_browser_sdk.waitForPhantomExtension)(3e3);
115
+ if (isMounted) {
116
+ setIsInstalled(result);
117
+ }
118
+ } catch (error) {
119
+ if (isMounted) {
120
+ setIsInstalled(false);
121
+ }
122
+ } finally {
123
+ if (isMounted) {
124
+ setIsLoading(false);
125
+ }
126
+ }
127
+ };
128
+ checkExtension();
129
+ return () => {
130
+ isMounted = false;
131
+ };
132
+ }, []);
133
+ return { isLoading, isInstalled };
134
+ }
135
+
136
+ // src/hooks/useIsPhantomLoginAvailable.ts
137
+ var React2 = __toESM(require("react"));
138
+ var import_browser_sdk2 = require("@phantom/browser-sdk");
139
+ function useIsPhantomLoginAvailable() {
140
+ const [isLoading, setIsLoading] = React2.useState(true);
141
+ const [isAvailable, setIsAvailable] = React2.useState(false);
142
+ React2.useEffect(() => {
143
+ let isMounted = true;
144
+ const checkPhantomLogin = async () => {
145
+ try {
146
+ setIsLoading(true);
147
+ const result = await (0, import_browser_sdk2.isPhantomLoginAvailable)(3e3);
148
+ if (isMounted) {
149
+ setIsAvailable(result);
150
+ }
151
+ } catch (error) {
152
+ if (isMounted) {
153
+ setIsAvailable(false);
154
+ }
155
+ } finally {
156
+ if (isMounted) {
157
+ setIsLoading(false);
158
+ }
159
+ }
160
+ };
161
+ checkPhantomLogin();
162
+ return () => {
163
+ isMounted = false;
164
+ };
165
+ }, []);
166
+ return { isLoading, isAvailable };
167
+ }
168
+
169
+ // src/hooks/useConnect.ts
170
+ var import_react3 = require("react");
171
+ function useConnect() {
172
+ const { sdk, isConnecting, isLoading, errors } = usePhantom();
173
+ const connect = (0, import_react3.useCallback)(
174
+ async (options) => {
175
+ if (!sdk) {
176
+ throw new Error("SDK not initialized");
177
+ }
178
+ try {
179
+ const result = await sdk.connect(options);
180
+ return result;
181
+ } catch (err) {
182
+ console.error("Error connecting to Phantom:", err);
183
+ throw err;
184
+ }
185
+ },
186
+ [sdk]
187
+ );
188
+ return {
189
+ connect,
190
+ isConnecting,
191
+ isLoading,
192
+ error: errors.connect
193
+ };
194
+ }
195
+
196
+ // src/hooks/useDiscoveredWallets.ts
197
+ var import_react4 = require("react");
198
+ function useDiscoveredWallets() {
199
+ const { sdk } = usePhantom();
200
+ const [wallets, setWallets] = (0, import_react4.useState)([]);
201
+ const [isLoading, setIsLoading] = (0, import_react4.useState)(true);
202
+ const [error, setError] = (0, import_react4.useState)(null);
203
+ const refetch = (0, import_react4.useCallback)(async () => {
204
+ if (!sdk) {
205
+ setWallets([]);
206
+ setError(null);
207
+ setIsLoading(false);
208
+ return;
209
+ }
210
+ try {
211
+ setIsLoading(true);
212
+ setError(null);
213
+ const initialWallets = sdk.getDiscoveredWallets();
214
+ if (initialWallets.length > 0) {
215
+ setWallets(initialWallets);
216
+ setIsLoading(false);
217
+ } else {
218
+ await sdk.discoverWallets();
219
+ const discoveredWallets = sdk.getDiscoveredWallets();
220
+ setWallets(discoveredWallets);
221
+ setIsLoading(false);
222
+ }
223
+ } catch (err) {
224
+ const error2 = err instanceof Error ? err : new Error("Failed to fetch discovered wallets");
225
+ setError(error2);
226
+ setWallets([]);
227
+ setIsLoading(false);
228
+ }
229
+ }, [sdk]);
230
+ (0, import_react4.useEffect)(() => {
231
+ refetch();
232
+ }, [refetch]);
233
+ return {
234
+ wallets,
235
+ isLoading,
236
+ error,
237
+ refetch
238
+ };
239
+ }
240
+
241
+ // src/components/ChainIcon.tsx
242
+ var import_wallet_sdk_ui = require("@phantom/wallet-sdk-ui");
52
243
  var import_jsx_runtime = require("react/jsx-runtime");
53
- var PhantomContext = (0, import_react.createContext)(void 0);
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);
58
- const [isConnected, setIsConnected] = (0, import_react.useState)(false);
59
- const [isConnecting, setIsConnecting] = (0, import_react.useState)(false);
60
- const [connectError, setConnectError] = (0, import_react.useState)(null);
61
- const [addresses, setAddresses] = (0, import_react.useState)([]);
62
- const [walletId, setWalletId] = (0, import_react.useState)(null);
63
- const [currentProviderType, setCurrentProviderType] = (0, import_react.useState)(
64
- memoizedConfig.providerType || null
244
+ var IconWrapper = ({ children }) => {
245
+ const theme = (0, import_wallet_sdk_ui.useTheme)();
246
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
247
+ "span",
248
+ {
249
+ style: {
250
+ display: "inline-flex",
251
+ alignItems: "center",
252
+ justifyContent: "center",
253
+ borderRadius: "4px",
254
+ backgroundColor: theme.aux,
255
+ color: theme.text,
256
+ padding: "2px"
257
+ },
258
+ children
259
+ }
65
260
  );
66
- const [isPhantomAvailable, setIsPhantomAvailable] = (0, import_react.useState)(false);
67
- (0, import_react.useEffect)(() => {
261
+ };
262
+ function ChainIcon({ addressType, size = 8 }) {
263
+ const theme = (0, import_wallet_sdk_ui.useTheme)();
264
+ const type = addressType.toLowerCase();
265
+ if (type.includes("solana")) {
266
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_wallet_sdk_ui.Icon, { type: "solana", size, color: theme.text }) });
267
+ }
268
+ if (type.includes("ethereum") || type.includes("evm")) {
269
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_wallet_sdk_ui.Icon, { type: "ethereum", size, color: theme.text }) });
270
+ }
271
+ if (type.includes("bitcoin")) {
272
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_wallet_sdk_ui.Icon, { type: "bitcoin", size, color: theme.text }) });
273
+ }
274
+ if (type.includes("sui")) {
275
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_wallet_sdk_ui.Icon, { type: "sui", size, color: theme.text }) });
276
+ }
277
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
278
+ "span",
279
+ {
280
+ style: {
281
+ display: "inline-flex",
282
+ alignItems: "center",
283
+ justifyContent: "center",
284
+ borderRadius: "4px",
285
+ backgroundColor: theme.aux,
286
+ color: theme.text,
287
+ fontSize: "6px",
288
+ fontWeight: "bold",
289
+ lineHeight: "1",
290
+ padding: "2px"
291
+ },
292
+ title: addressType,
293
+ children: addressType.charAt(0).toUpperCase()
294
+ }
295
+ );
296
+ }
297
+
298
+ // src/components/ConnectModalContent.tsx
299
+ var import_jsx_runtime2 = require("react/jsx-runtime");
300
+ function ConnectModalContent({
301
+ appIcon,
302
+ appName = "App Name",
303
+ onClose,
304
+ hideCloseButton = false
305
+ }) {
306
+ const theme = (0, import_wallet_sdk_ui2.useTheme)();
307
+ const { isLoading, allowedProviders } = usePhantom();
308
+ const baseConnect = useConnect();
309
+ const isExtensionInstalled = useIsExtensionInstalled();
310
+ const isPhantomLoginAvailable2 = useIsPhantomLoginAvailable();
311
+ const isMobile = (0, import_react5.useMemo)(() => (0, import_browser_sdk3.isMobileDevice)(), []);
312
+ const { wallets: discoveredWallets } = useDiscoveredWallets();
313
+ const [isConnecting, setIsConnecting] = (0, import_react5.useState)(false);
314
+ const [error, setError] = (0, import_react5.useState)(null);
315
+ const [providerType, setProviderType] = (0, import_react5.useState)(null);
316
+ const [showOtherWallets, setShowOtherWallets] = (0, import_react5.useState)(false);
317
+ const [selectedWalletId, setSelectedWalletId] = (0, import_react5.useState)(null);
318
+ const isConnectingState = baseConnect.isConnecting || isConnecting;
319
+ const errorState = baseConnect.error ? baseConnect.error.message : error;
320
+ const showDivider = !(allowedProviders.length === 1 && allowedProviders.includes("injected"));
321
+ const isInjectedOnly = allowedProviders.length === 1 && allowedProviders.includes("injected");
322
+ const shouldShowOtherWalletsButton = !isInjectedOnly && discoveredWallets.length > 2;
323
+ const walletsToShowInline = shouldShowOtherWalletsButton ? [] : discoveredWallets;
324
+ const connectWithAuthProvider = (0, import_react5.useCallback)(
325
+ async (provider, walletId) => {
326
+ try {
327
+ setIsConnecting(true);
328
+ setError(null);
329
+ setProviderType(provider);
330
+ setSelectedWalletId(walletId || null);
331
+ await baseConnect.connect({ provider, walletId });
332
+ onClose();
333
+ } catch {
334
+ const wallet = discoveredWallets.find((w) => w.id === walletId);
335
+ const providerName = wallet?.name || (0, import_constants.getProviderName)(provider);
336
+ setError(`Failed to connect to ${providerName}`);
337
+ } finally {
338
+ setIsConnecting(false);
339
+ setProviderType(null);
340
+ setSelectedWalletId(null);
341
+ }
342
+ },
343
+ [baseConnect, discoveredWallets, onClose]
344
+ );
345
+ const connectWithWallet = (0, import_react5.useCallback)(
346
+ async (wallet) => {
347
+ await connectWithAuthProvider("injected", wallet.id);
348
+ },
349
+ [connectWithAuthProvider]
350
+ );
351
+ const connectWithDeeplink = (0, import_react5.useCallback)(async () => {
352
+ try {
353
+ setIsConnecting(true);
354
+ setError(null);
355
+ setProviderType("deeplink");
356
+ await baseConnect.connect({ provider: "deeplink" });
357
+ onClose();
358
+ } catch (error2) {
359
+ const errorMessage = error2 instanceof Error ? error2.message : "Failed to open deeplink";
360
+ setError(errorMessage);
361
+ } finally {
362
+ setIsConnecting(false);
363
+ setProviderType(null);
364
+ }
365
+ }, [baseConnect, onClose]);
366
+ const appIconStyle = {
367
+ width: "56px",
368
+ height: "56px",
369
+ borderRadius: "50%",
370
+ display: "block",
371
+ objectFit: "cover",
372
+ marginBottom: "12px"
373
+ };
374
+ const connectContentContainerStyle = {
375
+ transition: "opacity 0.15s ease-in-out, transform 0.15s ease-in-out",
376
+ display: "flex",
377
+ flexDirection: "column",
378
+ alignItems: "center",
379
+ gap: "12px",
380
+ padding: "0 32px"
381
+ };
382
+ const otherWalletsContainerStyle = {
383
+ display: "flex",
384
+ flexDirection: "column",
385
+ alignItems: "center",
386
+ gap: "12px",
387
+ maxHeight: "480px",
388
+ overflowY: "auto",
389
+ padding: "0 32px 32px 32px",
390
+ transition: "opacity 0.15s ease-in-out, transform 0.15s ease-in-out"
391
+ };
392
+ const dividerStyle = {
393
+ display: "flex",
394
+ alignItems: "center",
395
+ width: "100%",
396
+ margin: "12px 0",
397
+ ...theme.typography.caption,
398
+ color: theme.secondary,
399
+ textTransform: "uppercase"
400
+ };
401
+ const dividerLineStyle = {
402
+ flex: 1,
403
+ height: "1px",
404
+ backgroundColor: (0, import_wallet_sdk_ui2.hexToRgba)(theme.secondary, 0.1)
405
+ };
406
+ const dividerTextStyle = {
407
+ padding: "0 12px"
408
+ };
409
+ const errorStyle = {
410
+ backgroundColor: "rgba(220, 53, 69, 0.1)",
411
+ color: "#ff6b6b",
412
+ border: "1px solid rgba(220, 53, 69, 0.3)",
413
+ borderRadius: theme.borderRadius,
414
+ boxSizing: "border-box",
415
+ padding: "12px",
416
+ width: "100%",
417
+ fontSize: "14px"
418
+ };
419
+ const loadingContainerStyle = {
420
+ display: "flex",
421
+ flexDirection: "column",
422
+ alignItems: "center",
423
+ justifyContent: "center",
424
+ padding: "24px",
425
+ gap: "12px"
426
+ };
427
+ const spinnerStyle = {
428
+ width: "40px",
429
+ height: "40px",
430
+ border: `3px solid ${theme.secondary}`,
431
+ borderTop: `3px solid ${theme.brand}`,
432
+ borderRadius: "50%",
433
+ animation: "spin 1s linear infinite"
434
+ };
435
+ const walletIconStyle = {
436
+ width: "32px",
437
+ height: "32px",
438
+ borderRadius: "8px",
439
+ objectFit: "cover"
440
+ };
441
+ const walletButtonContentStyle = {
442
+ display: "flex",
443
+ alignItems: "center",
444
+ justifyContent: "space-between",
445
+ gap: "8px",
446
+ width: "100%"
447
+ };
448
+ const walletButtonLeftStyle = {
449
+ display: "flex",
450
+ alignItems: "center",
451
+ gap: "8px",
452
+ flex: 1
453
+ };
454
+ const walletNameContainerStyle = {
455
+ display: "flex",
456
+ flexDirection: "column",
457
+ gap: "4px",
458
+ alignItems: "flex-start"
459
+ };
460
+ const chainIndicatorsStyle = {
461
+ display: "flex",
462
+ alignItems: "center",
463
+ gap: "4px"
464
+ };
465
+ const walletButtonRightStyle = {
466
+ display: "flex",
467
+ alignItems: "center",
468
+ gap: "8px",
469
+ color: theme.secondary
470
+ };
471
+ const footerStyle = {
472
+ display: "flex",
473
+ padding: "16px",
474
+ justifyContent: "center",
475
+ alignItems: "center",
476
+ gap: "4px",
477
+ borderTop: "1px solid rgba(152, 151, 156, 0.10)",
478
+ ...theme.typography.caption,
479
+ color: theme.secondary
480
+ };
481
+ const contentWrapperStyle = {
482
+ display: "flex",
483
+ flexDirection: "column",
484
+ justifyContent: "space-between",
485
+ gap: "24px"
486
+ };
487
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: contentWrapperStyle, children: [
488
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("style", { children: `
489
+ @keyframes spin {
490
+ 0% { transform: rotate(0deg); }
491
+ 100% { transform: rotate(360deg); }
492
+ }
493
+ ` }),
494
+ isLoading || baseConnect.isConnecting ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: loadingContainerStyle, children: [
495
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: spinnerStyle }),
496
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_wallet_sdk_ui2.Text, { variant: "label", color: theme.secondary, children: "Loading..." })
497
+ ] }) : showOtherWallets ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
498
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
499
+ import_wallet_sdk_ui2.ModalHeader,
500
+ {
501
+ goBack: true,
502
+ onGoBack: () => {
503
+ setError(null);
504
+ setShowOtherWallets(false);
505
+ },
506
+ title: "Other Wallets",
507
+ onClose,
508
+ hideCloseButton
509
+ }
510
+ ),
511
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: otherWalletsContainerStyle, children: [
512
+ errorState && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: errorStyle, children: errorState }),
513
+ discoveredWallets.map((wallet) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
514
+ import_wallet_sdk_ui2.Button,
515
+ {
516
+ onClick: () => connectWithWallet(wallet),
517
+ disabled: isConnectingState,
518
+ isLoading: isConnectingState && providerType === "injected" && selectedWalletId === wallet.id,
519
+ fullWidth: true,
520
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: walletButtonContentStyle, children: [
521
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: walletButtonLeftStyle, children: [
522
+ wallet.id === "phantom" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_wallet_sdk_ui2.BoundedIcon, { type: "phantom", size: 20, background: "#aba0f2", color: "white" }) : wallet.icon ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("img", { src: wallet.icon, alt: wallet.name, style: walletIconStyle }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_wallet_sdk_ui2.BoundedIcon, { type: "wallet", size: 20, background: theme.aux, color: theme.text }),
523
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: walletNameContainerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_wallet_sdk_ui2.Text, { variant: "captionBold", children: wallet.name }) })
524
+ ] }),
525
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: walletButtonRightStyle, children: [
526
+ wallet.addressTypes && wallet.addressTypes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: chainIndicatorsStyle, children: wallet.addressTypes.map((addressType) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChainIcon, { addressType, size: 8 }) }, `${wallet.id}-chain-${addressType}`)) }),
527
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_wallet_sdk_ui2.Icon, { type: "chevron-right", size: 16, color: theme.secondary })
528
+ ] })
529
+ ] })
530
+ },
531
+ wallet.id
532
+ ))
533
+ ] })
534
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
535
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_wallet_sdk_ui2.ModalHeader, { title: "Login or Sign Up", onClose, hideCloseButton }),
536
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: connectContentContainerStyle, children: [
537
+ appIcon && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("img", { src: appIcon, alt: appName, style: appIconStyle }),
538
+ errorState && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: errorStyle, children: errorState }),
539
+ isMobile && !isExtensionInstalled.isInstalled && allowedProviders.includes("deeplink") && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
540
+ import_wallet_sdk_ui2.LoginWithPhantomButton,
541
+ {
542
+ testId: "deeplink-button",
543
+ onClick: connectWithDeeplink,
544
+ disabled: isConnectingState,
545
+ isLoading: isConnectingState && providerType === "deeplink",
546
+ fullWidth: true,
547
+ children: isConnecting && providerType === "deeplink" ? "Opening Phantom..." : "Open in Phantom App"
548
+ }
549
+ ),
550
+ !isMobile && allowedProviders.includes("phantom") && isPhantomLoginAvailable2.isAvailable && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
551
+ import_wallet_sdk_ui2.LoginWithPhantomButton,
552
+ {
553
+ testId: "login-with-phantom-button",
554
+ onClick: () => connectWithAuthProvider("phantom"),
555
+ disabled: isConnectingState,
556
+ isLoading: isConnectingState && providerType === "phantom"
557
+ }
558
+ ),
559
+ allowedProviders.includes("google") && !(isMobile && isExtensionInstalled.isInstalled) && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
560
+ import_wallet_sdk_ui2.Button,
561
+ {
562
+ onClick: () => connectWithAuthProvider("google"),
563
+ disabled: isConnectingState,
564
+ isLoading: isConnectingState && providerType === "google",
565
+ fullWidth: true,
566
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: walletButtonContentStyle, children: [
567
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: walletButtonLeftStyle, children: [
568
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_wallet_sdk_ui2.Icon, { type: "google", size: 20 }),
569
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_wallet_sdk_ui2.Text, { variant: "captionBold", children: "Continue with Google" })
570
+ ] }),
571
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: walletButtonRightStyle, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_wallet_sdk_ui2.Icon, { type: "chevron-right", size: 16, color: theme.secondary }) })
572
+ ] })
573
+ }
574
+ ),
575
+ allowedProviders.includes("apple") && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
576
+ import_wallet_sdk_ui2.Button,
577
+ {
578
+ onClick: () => connectWithAuthProvider("apple"),
579
+ disabled: isConnectingState,
580
+ isLoading: isConnectingState && providerType === "apple",
581
+ fullWidth: true,
582
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: walletButtonContentStyle, children: [
583
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: walletButtonLeftStyle, children: [
584
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_wallet_sdk_ui2.Icon, { type: "apple", size: 20 }),
585
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_wallet_sdk_ui2.Text, { variant: "captionBold", children: "Continue with Apple" })
586
+ ] }),
587
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: walletButtonRightStyle, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_wallet_sdk_ui2.Icon, { type: "chevron-right", size: 16, color: theme.secondary }) })
588
+ ] })
589
+ }
590
+ ),
591
+ allowedProviders.includes("injected") && (isExtensionInstalled.isInstalled || discoveredWallets.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
592
+ showDivider && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: dividerStyle, children: [
593
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: dividerLineStyle }),
594
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: dividerTextStyle, children: "OR" }),
595
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: dividerLineStyle })
596
+ ] }),
597
+ walletsToShowInline.map((wallet) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
598
+ import_wallet_sdk_ui2.Button,
599
+ {
600
+ onClick: () => connectWithWallet(wallet),
601
+ disabled: isConnectingState,
602
+ isLoading: isConnectingState && providerType === "injected" && selectedWalletId === wallet.id,
603
+ fullWidth: true,
604
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: walletButtonContentStyle, children: [
605
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: walletButtonLeftStyle, children: [
606
+ wallet.id === "phantom" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_wallet_sdk_ui2.BoundedIcon, { type: "phantom", size: 20, background: "#aba0f2", color: "white" }) : wallet.icon ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("img", { src: wallet.icon, alt: wallet.name, style: walletIconStyle }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_wallet_sdk_ui2.BoundedIcon, { type: "wallet", size: 10, background: theme.aux, color: theme.text }),
607
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: walletNameContainerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_wallet_sdk_ui2.Text, { variant: "captionBold", children: wallet.name }) })
608
+ ] }),
609
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: walletButtonRightStyle, children: [
610
+ wallet.addressTypes && wallet.addressTypes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: chainIndicatorsStyle, children: wallet.addressTypes.map((addressType) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChainIcon, { addressType, size: 8 }) }, `${wallet.id}-chain-${addressType}`)) }),
611
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_wallet_sdk_ui2.Icon, { type: "chevron-right", size: 16, color: theme.secondary })
612
+ ] })
613
+ ] })
614
+ },
615
+ wallet.id
616
+ )),
617
+ shouldShowOtherWalletsButton && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_wallet_sdk_ui2.Button, { onClick: () => setShowOtherWallets(true), disabled: isConnectingState, fullWidth: true, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: walletButtonContentStyle, children: [
618
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: walletButtonLeftStyle, children: [
619
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_wallet_sdk_ui2.BoundedIcon, { type: "wallet", size: 20, background: theme.aux, color: theme.text }),
620
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_wallet_sdk_ui2.Text, { variant: "captionBold", children: "Other Wallets" })
621
+ ] }),
622
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: walletButtonRightStyle, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_wallet_sdk_ui2.Icon, { type: "chevron-right", size: 16, color: theme.secondary }) })
623
+ ] }) })
624
+ ] })
625
+ ] }),
626
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: footerStyle, children: [
627
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_wallet_sdk_ui2.Text, { variant: "label", color: theme.secondary, children: "Powered by" }),
628
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_wallet_sdk_ui2.Icon, { type: "phantom", size: 16 }),
629
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_wallet_sdk_ui2.Text, { variant: "label", color: theme.secondary, children: "Phantom" })
630
+ ] })
631
+ ] })
632
+ ] });
633
+ }
634
+
635
+ // src/components/ConnectedModalContent.tsx
636
+ var import_react7 = require("react");
637
+ var import_wallet_sdk_ui3 = require("@phantom/wallet-sdk-ui");
638
+
639
+ // src/hooks/useDisconnect.ts
640
+ var import_react6 = require("react");
641
+ function useDisconnect() {
642
+ const { sdk } = usePhantom();
643
+ const [isDisconnecting, setIsDisconnecting] = (0, import_react6.useState)(false);
644
+ const [error, setError] = (0, import_react6.useState)(null);
645
+ const disconnect = (0, import_react6.useCallback)(async () => {
646
+ if (!sdk) {
647
+ throw new Error("SDK not initialized");
648
+ }
649
+ setIsDisconnecting(true);
650
+ setError(null);
651
+ try {
652
+ await sdk.disconnect();
653
+ } catch (err) {
654
+ const error2 = err instanceof Error ? err : new Error(String(err));
655
+ setError(error2);
656
+ throw err;
657
+ } finally {
658
+ setIsDisconnecting(false);
659
+ }
660
+ }, [sdk]);
661
+ return {
662
+ disconnect,
663
+ isDisconnecting,
664
+ error
665
+ };
666
+ }
667
+
668
+ // src/components/ConnectedModalContent.tsx
669
+ var import_jsx_runtime3 = require("react/jsx-runtime");
670
+ function ConnectedModalContent({ onClose, hideCloseButton = false }) {
671
+ const theme = (0, import_wallet_sdk_ui3.useTheme)();
672
+ const { addresses } = usePhantom();
673
+ const { disconnect } = useDisconnect();
674
+ const [isDisconnecting, setIsDisconnecting] = (0, import_react7.useState)(false);
675
+ const [disconnectError, setDisconnectError] = (0, import_react7.useState)(null);
676
+ (0, import_react7.useEffect)(() => {
677
+ setDisconnectError(null);
678
+ }, []);
679
+ const handleDisconnect = async () => {
680
+ try {
681
+ setIsDisconnecting(true);
682
+ setDisconnectError(null);
683
+ await disconnect();
684
+ onClose();
685
+ } catch (err) {
686
+ const error = err instanceof Error ? err : new Error(String(err));
687
+ setDisconnectError(error);
688
+ } finally {
689
+ setIsDisconnecting(false);
690
+ }
691
+ };
692
+ const accountListStyle = {
693
+ display: "flex",
694
+ flexDirection: "column",
695
+ gap: "16px",
696
+ width: "100%",
697
+ minWidth: 0,
698
+ boxSizing: "border-box"
699
+ };
700
+ const accountItemStyle = {
701
+ display: "flex",
702
+ flexDirection: "column",
703
+ gap: "8px",
704
+ width: "100%",
705
+ minWidth: 0,
706
+ boxSizing: "border-box"
707
+ };
708
+ const addressTextStyle = {
709
+ fontFamily: "monospace",
710
+ wordBreak: "break-all",
711
+ overflowWrap: "break-word",
712
+ minWidth: 0
713
+ };
714
+ const errorContainerStyle = {
715
+ padding: "12px",
716
+ backgroundColor: "rgba(220, 53, 69, 0.1)",
717
+ borderRadius: theme.borderRadius,
718
+ border: "1px solid rgba(220, 53, 69, 0.3)",
719
+ width: "100%",
720
+ boxSizing: "border-box",
721
+ minWidth: 0
722
+ };
723
+ const contentWrapperStyle = {
724
+ display: "flex",
725
+ flexDirection: "column",
726
+ gap: "24px"
727
+ };
728
+ const accountListContainerStyle = {
729
+ display: "flex",
730
+ flexDirection: "column",
731
+ alignItems: "center",
732
+ gap: "12px",
733
+ padding: "0 32px 24px 32px",
734
+ boxSizing: "border-box",
735
+ width: "100%",
736
+ minWidth: 0
737
+ };
738
+ const disconnectButtonContainerStyle = {
739
+ display: "flex",
740
+ flexDirection: "column",
741
+ alignItems: "center",
742
+ gap: "12px",
743
+ padding: "0 32px 24px 32px",
744
+ boxSizing: "border-box",
745
+ width: "100%",
746
+ minWidth: 0
747
+ };
748
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: contentWrapperStyle, children: [
749
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_wallet_sdk_ui3.ModalHeader, { title: "Wallet", onClose, hideCloseButton }),
750
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: accountListContainerStyle, children: [
751
+ disconnectError && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: errorContainerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_wallet_sdk_ui3.Text, { variant: "caption", color: theme.error, children: "Failed to disconnect" }) }),
752
+ addresses && addresses.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: accountListStyle, children: addresses.map((account, index) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: accountItemStyle, children: [
753
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_wallet_sdk_ui3.Text, { variant: "label", color: theme.secondary, style: { textTransform: "uppercase" }, children: account.addressType }),
754
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: addressTextStyle, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_wallet_sdk_ui3.Text, { variant: "caption", children: account.address }) })
755
+ ] }, index)) })
756
+ ] }),
757
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: disconnectButtonContainerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_wallet_sdk_ui3.Button, { onClick: handleDisconnect, disabled: isDisconnecting, isLoading: isDisconnecting, fullWidth: true, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_wallet_sdk_ui3.Text, { variant: "captionBold", children: isDisconnecting ? "Disconnecting..." : "Disconnect" }) }) })
758
+ ] });
759
+ }
760
+
761
+ // src/components/SpendingLimitModalContent.tsx
762
+ var import_wallet_sdk_ui4 = require("@phantom/wallet-sdk-ui");
763
+ var import_jsx_runtime4 = require("react/jsx-runtime");
764
+ function SpendingLimitModalContent({ onClose }) {
765
+ const theme = (0, import_wallet_sdk_ui4.useTheme)();
766
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 16, padding: 32 }, children: [
767
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_wallet_sdk_ui4.Text, { variant: "caption", color: theme.secondary, children: "You've reached the maximum daily limit allowed to spend by this application." }),
768
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_wallet_sdk_ui4.Button, { fullWidth: true, onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_wallet_sdk_ui4.Text, { variant: "captionBold", children: "Close" }) })
769
+ ] });
770
+ }
771
+
772
+ // src/ModalProvider.tsx
773
+ var import_jsx_runtime5 = require("react/jsx-runtime");
774
+ function ModalProvider({ children, appIcon, appName }) {
775
+ const { isConnected, errors, clearError } = usePhantom();
776
+ const [isModalOpen, setIsModalOpen] = (0, import_react8.useState)(false);
777
+ const isMobile = (0, import_react8.useMemo)(() => (0, import_browser_sdk4.isMobileDevice)(), []);
778
+ const openModal = (0, import_react8.useCallback)(() => {
779
+ setIsModalOpen(true);
780
+ }, []);
781
+ const closeModal = (0, import_react8.useCallback)(() => {
782
+ setIsModalOpen(false);
783
+ clearError("spendingLimit");
784
+ }, [clearError]);
785
+ const isSpendingLimitOpen = !!errors.spendingLimit;
786
+ const modalContextValue = (0, import_react8.useMemo)(
787
+ () => ({
788
+ isModalOpen,
789
+ openModal,
790
+ closeModal
791
+ }),
792
+ [isModalOpen, openModal, closeModal]
793
+ );
794
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(ModalContext.Provider, { value: modalContextValue, children: [
795
+ children,
796
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
797
+ import_wallet_sdk_ui5.Modal,
798
+ {
799
+ isVisible: isModalOpen || isSpendingLimitOpen,
800
+ onClose: closeModal,
801
+ appIcon,
802
+ appName,
803
+ isMobile,
804
+ children: isSpendingLimitOpen ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SpendingLimitModalContent, { onClose: closeModal }) : isConnected ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ConnectedModalContent, { onClose: closeModal }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ConnectModalContent, { appIcon, appName, onClose: closeModal })
805
+ }
806
+ )
807
+ ] });
808
+ }
809
+
810
+ // src/PhantomProvider.tsx
811
+ var import_jsx_runtime6 = require("react/jsx-runtime");
812
+ function PhantomProvider({ children, config, debugConfig, theme, appIcon, appName }) {
813
+ const memoizedConfig = (0, import_react9.useMemo)(() => config, [config]);
814
+ const resolvedTheme = (0, import_react9.useMemo)(() => (0, import_wallet_sdk_ui6.mergeTheme)(theme || import_wallet_sdk_ui6.darkTheme), [theme]);
815
+ const [sdk, setSdk] = (0, import_react9.useState)(null);
816
+ const [isClient, setIsClient] = (0, import_react9.useState)(false);
817
+ const [isConnected, setIsConnected] = (0, import_react9.useState)(false);
818
+ const [isConnecting, setIsConnecting] = (0, import_react9.useState)(false);
819
+ const [isLoading, setIsLoading] = (0, import_react9.useState)(true);
820
+ const [errors, setErrors] = (0, import_react9.useState)({});
821
+ const [addresses, setAddresses] = (0, import_react9.useState)([]);
822
+ const [user, setUser] = (0, import_react9.useState)(null);
823
+ (0, import_react9.useEffect)(() => {
68
824
  setIsClient(true);
69
825
  }, []);
70
- (0, import_react.useEffect)(() => {
826
+ (0, import_react9.useEffect)(() => {
71
827
  if (!isClient)
72
828
  return;
73
- const sdkInstance = new import_browser_sdk.BrowserSDK(memoizedConfig);
829
+ const sdkInstance = new import_browser_sdk5.BrowserSDK(memoizedConfig);
74
830
  setSdk(sdkInstance);
75
831
  }, [isClient, memoizedConfig]);
76
- (0, import_react.useEffect)(() => {
832
+ (0, import_react9.useEffect)(() => {
77
833
  if (!sdk)
78
834
  return;
79
835
  const handleConnectStart = () => {
80
836
  setIsConnecting(true);
81
- setConnectError(null);
837
+ setErrors((prev) => ({ ...prev, connect: void 0 }));
82
838
  };
83
- const handleConnect = async () => {
839
+ const handleConnect = async (data) => {
84
840
  try {
85
841
  setIsConnected(true);
86
842
  setIsConnecting(false);
87
- const providerInfo = sdk.getCurrentProviderInfo();
88
- setCurrentProviderType(providerInfo?.type || null);
843
+ setUser(data);
89
844
  const addrs = await sdk.getAddresses();
90
845
  setAddresses(addrs);
91
- setWalletId(sdk.getWalletId());
92
846
  } catch (err) {
93
847
  console.error("Error connecting:", err);
94
848
  try {
@@ -101,127 +855,91 @@ function PhantomProvider({ children, config, debugConfig }) {
101
855
  const handleConnectError = (errorData) => {
102
856
  setIsConnecting(false);
103
857
  setIsConnected(false);
104
- setConnectError(new Error(errorData.error || "Connection failed"));
858
+ const isAutoConnectNoSession = errorData.source === "auto-connect" && (errorData.error === "No valid session found" || errorData.error === "No trusted connections available");
859
+ if (isAutoConnectNoSession) {
860
+ setErrors((prev) => ({ ...prev, connect: void 0 }));
861
+ } else {
862
+ setErrors((prev) => ({ ...prev, connect: new Error(errorData.error || "Connection failed") }));
863
+ }
864
+ setAddresses([]);
105
865
  };
106
866
  const handleDisconnect = () => {
107
867
  setIsConnected(false);
108
868
  setIsConnecting(false);
109
- setConnectError(null);
869
+ setErrors({});
110
870
  setAddresses([]);
111
- setWalletId(null);
871
+ setUser(null);
872
+ };
873
+ const handleSpendingLimitReached = () => {
874
+ setErrors((prev) => ({ ...prev, spendingLimit: true }));
112
875
  };
113
876
  sdk.on("connect_start", handleConnectStart);
114
877
  sdk.on("connect", handleConnect);
115
878
  sdk.on("connect_error", handleConnectError);
116
879
  sdk.on("disconnect", handleDisconnect);
880
+ sdk.on("spending_limit_reached", handleSpendingLimitReached);
117
881
  return () => {
118
882
  sdk.off("connect_start", handleConnectStart);
119
883
  sdk.off("connect", handleConnect);
120
884
  sdk.off("connect_error", handleConnectError);
121
885
  sdk.off("disconnect", handleDisconnect);
886
+ sdk.off("spending_limit_reached", handleSpendingLimitReached);
122
887
  };
123
888
  }, [sdk]);
124
- (0, import_react.useEffect)(() => {
889
+ (0, import_react9.useEffect)(() => {
125
890
  if (!debugConfig || !sdk)
126
891
  return;
127
892
  sdk.configureDebug(debugConfig);
128
893
  }, [sdk, debugConfig]);
129
- (0, import_react.useEffect)(() => {
894
+ (0, import_react9.useEffect)(() => {
130
895
  if (!isClient || !sdk)
131
896
  return;
132
897
  const initialize = async () => {
133
898
  try {
134
- const available = await import_browser_sdk.BrowserSDK.isPhantomInstalled();
135
- setIsPhantomAvailable(available);
136
- } catch (err) {
137
- console.error("Error checking Phantom extension:", err);
138
- setIsPhantomAvailable(false);
139
- }
140
- if (memoizedConfig.autoConnect !== false) {
141
- sdk.autoConnect().catch(() => {
142
- });
899
+ await sdk.autoConnect();
900
+ } catch (error) {
901
+ console.error("Auto-connect error:", error);
143
902
  }
903
+ setIsLoading(false);
144
904
  };
145
905
  initialize();
146
- }, [sdk, memoizedConfig.autoConnect, isClient]);
147
- const value = (0, import_react.useMemo)(
906
+ }, [sdk, isClient]);
907
+ const clearError = (0, import_react9.useCallback)((key) => {
908
+ setErrors((prev) => {
909
+ const next = { ...prev };
910
+ delete next[key];
911
+ return next;
912
+ });
913
+ }, []);
914
+ const value = (0, import_react9.useMemo)(
148
915
  () => ({
149
916
  sdk,
150
917
  isConnected,
151
918
  isConnecting,
152
- connectError,
919
+ isLoading,
920
+ errors,
153
921
  addresses,
154
- walletId,
155
- currentProviderType,
156
- isPhantomAvailable,
157
- isClient
922
+ isClient,
923
+ user,
924
+ theme: resolvedTheme,
925
+ allowedProviders: memoizedConfig.providers,
926
+ clearError
158
927
  }),
159
- [sdk, isConnected, isConnecting, connectError, addresses, walletId, currentProviderType, isPhantomAvailable, isClient]
160
- );
161
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PhantomContext.Provider, { value, children });
162
- }
163
- function usePhantom() {
164
- const context = (0, import_react.useContext)(PhantomContext);
165
- if (!context) {
166
- throw new Error("usePhantom must be used within a PhantomProvider");
167
- }
168
- return context;
169
- }
170
-
171
- // src/hooks/useConnect.ts
172
- var import_react2 = require("react");
173
- function useConnect() {
174
- const { sdk, isConnecting, connectError, currentProviderType, isPhantomAvailable } = usePhantom();
175
- const connect = (0, import_react2.useCallback)(
176
- async (options) => {
177
- if (!sdk) {
178
- throw new Error("SDK not initialized");
179
- }
180
- try {
181
- const result = await sdk.connect(options);
182
- return result;
183
- } catch (err) {
184
- console.error("Error connecting to Phantom:", err);
185
- throw err;
186
- }
187
- },
188
- [sdk]
928
+ [
929
+ sdk,
930
+ isConnected,
931
+ isConnecting,
932
+ isLoading,
933
+ errors,
934
+ addresses,
935
+ isClient,
936
+ user,
937
+ resolvedTheme,
938
+ memoizedConfig.providers,
939
+ clearError
940
+ ]
189
941
  );
190
- return {
191
- connect,
192
- isConnecting,
193
- error: connectError,
194
- currentProviderType,
195
- isPhantomAvailable
196
- };
197
- }
198
-
199
- // src/hooks/useDisconnect.ts
200
- var import_react3 = require("react");
201
- function useDisconnect() {
202
- const { sdk } = usePhantom();
203
- const [isDisconnecting, setIsDisconnecting] = (0, import_react3.useState)(false);
204
- const [error, setError] = (0, import_react3.useState)(null);
205
- const disconnect = (0, import_react3.useCallback)(async () => {
206
- if (!sdk) {
207
- throw new Error("SDK not initialized");
208
- }
209
- setIsDisconnecting(true);
210
- setError(null);
211
- try {
212
- await sdk.disconnect();
213
- } catch (err) {
214
- setError(err);
215
- throw err;
216
- } finally {
217
- setIsDisconnecting(false);
218
- }
219
- }, [sdk]);
220
- return {
221
- disconnect,
222
- isDisconnecting,
223
- error
224
- };
942
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_wallet_sdk_ui6.ThemeProvider, { theme: resolvedTheme, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(PhantomContext.Provider, { value, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ModalProvider, { appIcon, appName, children }) }) });
225
943
  }
226
944
 
227
945
  // src/hooks/useAccounts.ts
@@ -230,49 +948,16 @@ function useAccounts() {
230
948
  return isConnected ? addresses : null;
231
949
  }
232
950
 
233
- // src/hooks/useIsExtensionInstalled.ts
234
- var React = __toESM(require("react"));
235
- var import_browser_sdk2 = require("@phantom/browser-sdk");
236
- function useIsExtensionInstalled() {
237
- const [isLoading, setIsLoading] = React.useState(true);
238
- const [isInstalled, setIsInstalled] = React.useState(false);
239
- React.useEffect(() => {
240
- let isMounted = true;
241
- const checkExtension = async () => {
242
- try {
243
- setIsLoading(true);
244
- const result = await (0, import_browser_sdk2.waitForPhantomExtension)(3e3);
245
- if (isMounted) {
246
- setIsInstalled(result);
247
- }
248
- } catch (error) {
249
- if (isMounted) {
250
- setIsInstalled(false);
251
- }
252
- } finally {
253
- if (isMounted) {
254
- setIsLoading(false);
255
- }
256
- }
257
- };
258
- checkExtension();
259
- return () => {
260
- isMounted = false;
261
- };
262
- }, []);
263
- return { isLoading, isInstalled };
264
- }
265
-
266
951
  // src/hooks/useAutoConfirm.ts
267
- var import_react4 = require("react");
952
+ var import_react10 = require("react");
268
953
  function useAutoConfirm() {
269
- const { sdk, currentProviderType } = usePhantom();
270
- const [status, setStatus] = (0, import_react4.useState)(null);
271
- const [supportedChains, setSupportedChains] = (0, import_react4.useState)(null);
272
- const [isLoading, setIsLoading] = (0, import_react4.useState)(false);
273
- const [error, setError] = (0, import_react4.useState)(null);
274
- const isInjected = currentProviderType === "injected";
275
- const enable = (0, import_react4.useCallback)(
954
+ const { sdk, user } = usePhantom();
955
+ const [status, setStatus] = (0, import_react10.useState)(null);
956
+ const [supportedChains, setSupportedChains] = (0, import_react10.useState)(null);
957
+ const [isLoading, setIsLoading] = (0, import_react10.useState)(false);
958
+ const [error, setError] = (0, import_react10.useState)(null);
959
+ const isInjected = user?.authProvider === "injected";
960
+ const enable = (0, import_react10.useCallback)(
276
961
  async (params) => {
277
962
  if (!sdk) {
278
963
  throw new Error("SDK not initialized");
@@ -296,7 +981,7 @@ function useAutoConfirm() {
296
981
  },
297
982
  [sdk, isInjected]
298
983
  );
299
- const disable = (0, import_react4.useCallback)(async () => {
984
+ const disable = (0, import_react10.useCallback)(async () => {
300
985
  if (!sdk) {
301
986
  throw new Error("SDK not initialized");
302
987
  }
@@ -317,7 +1002,7 @@ function useAutoConfirm() {
317
1002
  setIsLoading(false);
318
1003
  }
319
1004
  }, [sdk, isInjected]);
320
- const refetch = (0, import_react4.useCallback)(async () => {
1005
+ const refetch = (0, import_react10.useCallback)(async () => {
321
1006
  if (!sdk || !isInjected) {
322
1007
  return;
323
1008
  }
@@ -337,7 +1022,7 @@ function useAutoConfirm() {
337
1022
  setIsLoading(false);
338
1023
  }
339
1024
  }, [sdk, isInjected]);
340
- (0, import_react4.useEffect)(() => {
1025
+ (0, import_react10.useEffect)(() => {
341
1026
  if (sdk && isInjected) {
342
1027
  refetch();
343
1028
  } else {
@@ -358,40 +1043,150 @@ function useAutoConfirm() {
358
1043
  }
359
1044
 
360
1045
  // src/hooks/useSolana.ts
1046
+ var import_browser_sdk6 = require("@phantom/browser-sdk");
361
1047
  function useSolana() {
362
- const { sdk, isConnected, isClient } = usePhantom();
363
- if (!isClient || !sdk) {
1048
+ const { sdk, isClient, isLoading } = usePhantom();
1049
+ if (!isClient || !sdk || isLoading) {
1050
+ return {
1051
+ solana: {},
1052
+ isAvailable: false
1053
+ };
1054
+ }
1055
+ const enabledAddressTypes = sdk.getEnabledAddressTypes();
1056
+ const isAvailable = enabledAddressTypes.includes(import_browser_sdk6.AddressType.solana);
1057
+ if (!isAvailable) {
1058
+ return {
1059
+ solana: {},
1060
+ isAvailable: false
1061
+ };
1062
+ }
1063
+ try {
1064
+ return {
1065
+ solana: sdk.solana,
1066
+ isAvailable: true
1067
+ };
1068
+ } catch (error) {
364
1069
  return {
365
1070
  solana: {},
366
- // This will be replaced when SDK is ready
367
1071
  isAvailable: false
368
1072
  };
369
1073
  }
370
- return {
371
- // Chain instance with connection enforcement for signing methods
372
- solana: sdk.solana,
373
- // State
374
- isAvailable: !!isConnected
375
- };
376
1074
  }
377
1075
 
378
1076
  // src/hooks/useEthereum.ts
1077
+ var import_browser_sdk7 = require("@phantom/browser-sdk");
379
1078
  function useEthereum() {
380
- const { sdk, isConnected, isClient } = usePhantom();
381
- if (!isClient || !sdk) {
1079
+ const { sdk, isClient, isLoading } = usePhantom();
1080
+ if (!isClient || !sdk || isLoading) {
382
1081
  return {
383
1082
  ethereum: {},
384
- // This will be replaced when SDK is ready
385
1083
  isAvailable: false
386
1084
  };
387
1085
  }
388
- return {
389
- // Chain instance with connection enforcement for signing methods
390
- ethereum: sdk.ethereum,
391
- // State
392
- isAvailable: !!isConnected
1086
+ const enabledAddressTypes = sdk.getEnabledAddressTypes();
1087
+ const isAvailable = enabledAddressTypes.includes(import_browser_sdk7.AddressType.ethereum);
1088
+ if (!isAvailable) {
1089
+ return {
1090
+ ethereum: {},
1091
+ isAvailable: false
1092
+ };
1093
+ }
1094
+ try {
1095
+ return {
1096
+ ethereum: sdk.ethereum,
1097
+ isAvailable: true
1098
+ };
1099
+ } catch (error) {
1100
+ return {
1101
+ ethereum: {},
1102
+ isAvailable: false
1103
+ };
1104
+ }
1105
+ }
1106
+
1107
+ // src/hooks/index.ts
1108
+ var import_wallet_sdk_ui7 = require("@phantom/wallet-sdk-ui");
1109
+
1110
+ // src/components/ConnectButton.tsx
1111
+ var import_react11 = require("react");
1112
+ var import_wallet_sdk_ui8 = require("@phantom/wallet-sdk-ui");
1113
+ var import_jsx_runtime7 = require("react/jsx-runtime");
1114
+ function ConnectButton({ addressType, fullWidth = false }) {
1115
+ const theme = (0, import_wallet_sdk_ui8.useTheme)();
1116
+ const { open } = useModal();
1117
+ const { isConnected, addresses } = usePhantom();
1118
+ const displayAddress = (0, import_react11.useMemo)(() => {
1119
+ if (!addresses || addresses.length === 0)
1120
+ return null;
1121
+ if (addressType) {
1122
+ return addresses.find((addr) => addr.addressType === addressType);
1123
+ }
1124
+ return addresses[0];
1125
+ }, [addresses, addressType]);
1126
+ const truncatedAddress = (0, import_react11.useMemo)(() => {
1127
+ if (!displayAddress)
1128
+ return "";
1129
+ const addr = displayAddress.address;
1130
+ if (addr.length <= 12)
1131
+ return addr;
1132
+ return `${addr.slice(0, 6)}...${addr.slice(-4)}`;
1133
+ }, [displayAddress]);
1134
+ const buttonStyle = {
1135
+ width: fullWidth ? "100%" : "auto",
1136
+ padding: "12px 16px",
1137
+ border: "none",
1138
+ borderRadius: theme.borderRadius,
1139
+ fontFamily: theme.typography.captionBold.fontFamily,
1140
+ fontSize: theme.typography.captionBold.fontSize,
1141
+ fontStyle: theme.typography.captionBold.fontStyle,
1142
+ fontWeight: theme.typography.captionBold.fontWeight,
1143
+ lineHeight: theme.typography.captionBold.lineHeight,
1144
+ letterSpacing: theme.typography.captionBold.letterSpacing,
1145
+ cursor: "pointer",
1146
+ transition: "background-color 0.2s",
1147
+ display: "flex",
1148
+ alignItems: "center",
1149
+ justifyContent: "center",
1150
+ gap: "8px",
1151
+ background: theme.aux,
1152
+ color: theme.text
393
1153
  };
1154
+ const connectedButtonStyle = {
1155
+ ...buttonStyle,
1156
+ background: theme.aux,
1157
+ cursor: "pointer"
1158
+ };
1159
+ if (isConnected && displayAddress) {
1160
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { style: connectedButtonStyle, onClick: open, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { fontFamily: "monospace" }, children: truncatedAddress }) });
1161
+ }
1162
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { style: buttonStyle, onClick: open, children: "Connect Wallet" });
1163
+ }
1164
+
1165
+ // src/components/ConnectBox.tsx
1166
+ var import_react12 = require("react");
1167
+ var import_wallet_sdk_ui9 = require("@phantom/wallet-sdk-ui");
1168
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1169
+ function ConnectBox({ maxWidth = "350px", transparent = false, appIcon, appName }) {
1170
+ const theme = (0, import_wallet_sdk_ui9.useTheme)();
1171
+ const { isConnected } = usePhantom();
1172
+ const boxStyle = (0, import_react12.useMemo)(() => {
1173
+ const style = {
1174
+ width: "100%",
1175
+ maxWidth: typeof maxWidth === "number" ? `${maxWidth}px` : maxWidth,
1176
+ position: "relative",
1177
+ overflow: "hidden"
1178
+ };
1179
+ if (!transparent) {
1180
+ style.backgroundColor = theme.background;
1181
+ style.borderRadius = theme.borderRadius;
1182
+ }
1183
+ return style;
1184
+ }, [maxWidth, transparent, theme.background, theme.borderRadius]);
1185
+ const noOp = () => {
1186
+ };
1187
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: boxStyle, children: isConnected ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ConnectedModalContent, { onClose: noOp, hideCloseButton: true }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ConnectModalContent, { appIcon, appName, onClose: noOp, hideCloseButton: true }) });
394
1188
  }
395
1189
 
396
1190
  // src/index.ts
397
- var import_browser_sdk3 = require("@phantom/browser-sdk");
1191
+ var import_wallet_sdk_ui10 = require("@phantom/wallet-sdk-ui");
1192
+ var import_browser_sdk8 = require("@phantom/browser-sdk");