signer-test-sdk-react 0.0.11 → 0.0.13

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.
Files changed (91) hide show
  1. package/README.md +1 -1
  2. package/dist/src/AbstraxnProvider.d.ts +2 -5
  3. package/dist/src/AbstraxnProvider.js +550 -50
  4. package/dist/src/AbstraxnProvider.js.map +1 -1
  5. package/dist/src/WalletModal.css +1973 -23
  6. package/dist/src/WalletModal.d.ts +2 -1
  7. package/dist/src/WalletModal.js +200 -30
  8. package/dist/src/WalletModal.js.map +1 -1
  9. package/dist/src/chains.d.ts +55 -0
  10. package/dist/src/chains.js +221 -0
  11. package/dist/src/chains.js.map +1 -0
  12. package/dist/src/components/OnboardingUI/OnboardingUIReact.js +24 -3
  13. package/dist/src/components/OnboardingUI/OnboardingUIReact.js.map +1 -1
  14. package/dist/src/components/OnboardingUI/OnboardingUIWeb.d.ts +11 -2
  15. package/dist/src/components/OnboardingUI/OnboardingUIWeb.js +266 -36
  16. package/dist/src/components/OnboardingUI/OnboardingUIWeb.js.map +1 -1
  17. package/dist/src/components/OnboardingUI/components/PasskeyButton.js +1 -1
  18. package/dist/src/components/OnboardingUI/components/PasskeyButton.js.map +1 -1
  19. package/dist/src/components/QRCode.d.ts +13 -0
  20. package/dist/src/components/QRCode.js +6 -0
  21. package/dist/src/components/QRCode.js.map +1 -0
  22. package/dist/src/components/WalletModal/components/ChainSelector.css +180 -0
  23. package/dist/src/components/WalletModal/components/ChainSelector.d.ts +10 -0
  24. package/dist/src/components/WalletModal/components/ChainSelector.js +34 -0
  25. package/dist/src/components/WalletModal/components/ChainSelector.js.map +1 -0
  26. package/dist/src/components/WalletModal/components/ExportKeyModal.css +133 -0
  27. package/dist/src/components/WalletModal/components/ExportKeyModal.d.ts +9 -0
  28. package/dist/src/components/WalletModal/components/ExportKeyModal.js +31 -0
  29. package/dist/src/components/WalletModal/components/ExportKeyModal.js.map +1 -0
  30. package/dist/src/components/WalletModal/components/ExportWarningModal.css +2 -0
  31. package/dist/src/components/WalletModal/components/ExportWarningModal.d.ts +11 -0
  32. package/dist/src/components/WalletModal/components/ExportWarningModal.js +18 -0
  33. package/dist/src/components/WalletModal/components/ExportWarningModal.js.map +1 -0
  34. package/dist/src/components/WalletModal/components/ManageWalletModal.css +160 -0
  35. package/dist/src/components/WalletModal/components/ManageWalletModal.d.ts +12 -0
  36. package/dist/src/components/WalletModal/components/ManageWalletModal.js +21 -0
  37. package/dist/src/components/WalletModal/components/ManageWalletModal.js.map +1 -0
  38. package/dist/src/components/WalletModal/components/PreviewTransactionModal.css +128 -0
  39. package/dist/src/components/WalletModal/components/PreviewTransactionModal.d.ts +17 -0
  40. package/dist/src/components/WalletModal/components/PreviewTransactionModal.js +10 -0
  41. package/dist/src/components/WalletModal/components/PreviewTransactionModal.js.map +1 -0
  42. package/dist/src/components/WalletModal/components/ReceiveModal.css +101 -0
  43. package/dist/src/components/WalletModal/components/ReceiveModal.d.ts +8 -0
  44. package/dist/src/components/WalletModal/components/ReceiveModal.js +22 -0
  45. package/dist/src/components/WalletModal/components/ReceiveModal.js.map +1 -0
  46. package/dist/src/components/WalletModal/components/SendModal.css +234 -0
  47. package/dist/src/components/WalletModal/components/SendModal.d.ts +18 -0
  48. package/dist/src/components/WalletModal/components/SendModal.js +127 -0
  49. package/dist/src/components/WalletModal/components/SendModal.js.map +1 -0
  50. package/dist/src/components/WalletModal/components/SuccessModal.css +86 -0
  51. package/dist/src/components/WalletModal/components/SuccessModal.d.ts +13 -0
  52. package/dist/src/components/WalletModal/components/SuccessModal.js +8 -0
  53. package/dist/src/components/WalletModal/components/SuccessModal.js.map +1 -0
  54. package/dist/src/components/WalletModal/components/UserAvatar.d.ts +9 -0
  55. package/dist/src/components/WalletModal/components/UserAvatar.js +31 -0
  56. package/dist/src/components/WalletModal/components/UserAvatar.js.map +1 -0
  57. package/dist/src/components/WalletModal/components/index.d.ts +21 -0
  58. package/dist/src/components/WalletModal/components/index.js +13 -0
  59. package/dist/src/components/WalletModal/components/index.js.map +1 -0
  60. package/dist/src/components/WalletModal/hooks/index.d.ts +6 -0
  61. package/dist/src/components/WalletModal/hooks/index.js +7 -0
  62. package/dist/src/components/WalletModal/hooks/index.js.map +1 -0
  63. package/dist/src/components/WalletModal/hooks/useAddressValidation.d.ts +4 -0
  64. package/dist/src/components/WalletModal/hooks/useAddressValidation.js +17 -0
  65. package/dist/src/components/WalletModal/hooks/useAddressValidation.js.map +1 -0
  66. package/dist/src/components/WalletModal/hooks/useAmountValidation.d.ts +4 -0
  67. package/dist/src/components/WalletModal/hooks/useAmountValidation.js +29 -0
  68. package/dist/src/components/WalletModal/hooks/useAmountValidation.js.map +1 -0
  69. package/dist/src/components/WalletModal/hooks/useSendTransaction.d.ts +20 -0
  70. package/dist/src/components/WalletModal/hooks/useSendTransaction.js +55 -0
  71. package/dist/src/components/WalletModal/hooks/useSendTransaction.js.map +1 -0
  72. package/dist/src/components/WalletModal/index.d.ts +5 -0
  73. package/dist/src/components/WalletModal/index.js +7 -0
  74. package/dist/src/components/WalletModal/index.js.map +1 -0
  75. package/dist/src/components/WalletModal/utils/addressUtils.d.ts +19 -0
  76. package/dist/src/components/WalletModal/utils/addressUtils.js +62 -0
  77. package/dist/src/components/WalletModal/utils/addressUtils.js.map +1 -0
  78. package/dist/src/components/WalletModal/utils/formatUtils.d.ts +20 -0
  79. package/dist/src/components/WalletModal/utils/formatUtils.js +47 -0
  80. package/dist/src/components/WalletModal/utils/formatUtils.js.map +1 -0
  81. package/dist/src/components/WalletModal/utils/index.d.ts +5 -0
  82. package/dist/src/components/WalletModal/utils/index.js +6 -0
  83. package/dist/src/components/WalletModal/utils/index.js.map +1 -0
  84. package/dist/src/index.d.ts +2 -1
  85. package/dist/src/index.js +1 -0
  86. package/dist/src/index.js.map +1 -1
  87. package/dist/src/types.d.ts +29 -0
  88. package/dist/src/wagmiConfig.js +6 -2
  89. package/dist/src/wagmiConfig.js.map +1 -1
  90. package/dist/tsconfig.tsbuildinfo +1 -1
  91. package/package.json +8 -8
@@ -1,26 +1,19 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  /**
3
3
  * Abstraxn Wallet Provider - React Context Provider
4
4
  * Wrap your app with this provider to use Abstraxn Wallet SDK
5
5
  */
6
- import { createContext, useContext, useEffect, useState, useRef, useCallback, useMemo } from 'react';
6
+ import React, { createContext, useContext, useEffect, useState, useRef, useCallback, useMemo } from 'react';
7
7
  import { AbstraxnWallet, AuthenticationError } from 'signer-test-sdk-core';
8
8
  import { OnboardingUIWeb } from './components/OnboardingUI';
9
9
  import { WagmiProvider, useAccount, useConnect, useDisconnect, useSignMessage, useSendTransaction, useSwitchChain, useBalance, useChainId } from 'wagmi';
10
10
  import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
11
11
  import { createWagmiConfig } from './wagmiConfig';
12
- import { parseEther } from 'viem';
12
+ import { parseEther, createPublicClient, http } from 'viem';
13
13
  import { ExternalWalletButtons } from './ExternalWalletButtons';
14
+ import { EVM_CHAINS, SOLANA_CHAINS, getChainById, toCoreChain } from './chains';
14
15
  export const AbstraxnContext = createContext(null);
15
- // Create a default QueryClient for wagmi
16
- const defaultQueryClient = new QueryClient({
17
- defaultOptions: {
18
- queries: {
19
- refetchOnWindowFocus: false,
20
- retry: false,
21
- },
22
- },
23
- });
16
+ // QueryClient will be created inside the component to ensure React context is available
24
17
  // Base provider logic (shared between with and without wagmi)
25
18
  function useAbstraxnProviderBase(_config) {
26
19
  const [isInitialized, setIsInitialized] = useState(false);
@@ -31,6 +24,7 @@ function useAbstraxnProviderBase(_config) {
31
24
  const [chainId, setChainId] = useState(null);
32
25
  const [error, setError] = useState(null);
33
26
  const [loading, setLoading] = useState(false);
27
+ const [walletBalance, setWalletBalance] = useState(null);
34
28
  const onboardingRef = useRef(null);
35
29
  const otpIdRef = useRef(null);
36
30
  const walletRef = useRef(null);
@@ -46,6 +40,7 @@ function useAbstraxnProviderBase(_config) {
46
40
  chainId, setChainId,
47
41
  error, setError,
48
42
  loading, setLoading,
43
+ walletBalance, setWalletBalance,
49
44
  onboardingRef, otpIdRef, walletRef, googleCallbackHandledRef, twitterCallbackHandledRef, discordCallbackHandledRef,
50
45
  };
51
46
  }
@@ -83,7 +78,7 @@ function AbstraxnProviderWithoutWagmi({ config, children }) {
83
78
  return _jsx(AbstraxnProviderInner, { config: config, children: children, base: base, wagmi: null });
84
79
  }
85
80
  function AbstraxnProviderInner({ config, children, base, wagmi }) {
86
- const { isInitialized, setIsInitialized, isConnected, setIsConnected, address, setAddress, user, setUser, whoami, setWhoami, chainId, setChainId, error, setError, loading, setLoading, onboardingRef, otpIdRef, walletRef, googleCallbackHandledRef, twitterCallbackHandledRef, discordCallbackHandledRef, } = base;
81
+ const { isInitialized, setIsInitialized, isConnected, setIsConnected, address, setAddress, user, setUser, whoami, setWhoami, chainId, setChainId, error, setError, loading, setLoading, walletBalance, setWalletBalance, onboardingRef, otpIdRef, walletRef, googleCallbackHandledRef, twitterCallbackHandledRef, discordCallbackHandledRef, } = base;
87
82
  const externalWalletsEnabled = config.externalWallets?.enabled ?? false;
88
83
  // Keep a ref to avoid re-creating callbacks when toggling config (prevents flicker)
89
84
  const externalWalletsEnabledRef = useRef(externalWalletsEnabled);
@@ -144,18 +139,105 @@ function AbstraxnProviderInner({ config, children, base, wagmi }) {
144
139
  }
145
140
  });
146
141
  }, [externalWalletsEnabled]);
142
+ // Restore external wallet connection on mount if wagmi has already restored it
143
+ // This runs after wagmi has had time to restore from localStorage
144
+ useEffect(() => {
145
+ if (!externalWalletsEnabled || !wagmiAccount) {
146
+ return;
147
+ }
148
+ // Check if wagmi has already restored a connection from localStorage
149
+ // This happens automatically with wagmi's persistence when storage is configured
150
+ const checkAndRestore = () => {
151
+ if (wagmiAccount.isConnected && wagmiAccount.address && !isExternalWalletConnected) {
152
+ const walletAddress = wagmiAccount.address.toLowerCase();
153
+ const currentChainId = wagmiChainIdHook || wagmiAccount.chainId || null;
154
+ // Set explicitConnectionRef FIRST to prevent auto-disconnect from interfering
155
+ explicitConnectionRef.current = true;
156
+ autoDisconnectHandledRef.current = false;
157
+ // Restore external wallet state
158
+ setIsExternalWalletConnected(true);
159
+ setExternalWalletAddress(walletAddress);
160
+ setAddress(walletAddress);
161
+ setIsConnected(true);
162
+ setExternalWalletChainId(currentChainId);
163
+ setChainId(currentChainId);
164
+ // Update refs to track the restored connection
165
+ lastAddressRef.current = walletAddress;
166
+ lastChainIdRef.current = currentChainId;
167
+ lastConnectionTimeRef.current = Date.now();
168
+ return true; // Indicate restoration happened
169
+ }
170
+ return false;
171
+ };
172
+ // Check immediately
173
+ if (checkAndRestore()) {
174
+ return; // Already restored
175
+ }
176
+ // Also check after delays to catch wagmi's async restoration
177
+ // Wagmi might restore the connection asynchronously after the component mounts
178
+ let timeout2 = null;
179
+ const timeout1 = setTimeout(() => {
180
+ if (!checkAndRestore()) {
181
+ // Check one more time after a longer delay
182
+ timeout2 = setTimeout(() => {
183
+ checkAndRestore();
184
+ }, 300);
185
+ }
186
+ }, 150);
187
+ return () => {
188
+ clearTimeout(timeout1);
189
+ if (timeout2) {
190
+ clearTimeout(timeout2);
191
+ }
192
+ };
193
+ }, [externalWalletsEnabled, wagmiAccount?.isConnected, wagmiAccount?.address, wagmiChainIdHook, isExternalWalletConnected]); // Re-run if wagmi state changes
147
194
  // Initialize wallet
148
195
  useEffect(() => {
149
196
  // If wallet already exists (from previous mount), reuse it to prevent flicker
150
197
  if (walletRef.current) {
151
198
  return;
152
199
  }
200
+ // Compute supported chains from chain config (outside useMemo since we're in useEffect)
201
+ // This should include ALL chains that might be shown in the UI (availableChains)
202
+ // We use the same logic as availableChains to ensure consistency
203
+ let computedSupportedChains = undefined;
204
+ if (config.supportedChains) {
205
+ // Use explicitly provided chains
206
+ computedSupportedChains = config.supportedChains;
207
+ }
208
+ else {
209
+ // Compute from chains config - use same logic as availableChains
210
+ const chainConfig = config.chains;
211
+ const chains = [];
212
+ // Priority 1: Check new chains config format
213
+ if (chainConfig?.supportedEvmChains && chainConfig.supportedEvmChains.length > 0) {
214
+ chainConfig.supportedEvmChains.forEach(chainName => {
215
+ const chainData = EVM_CHAINS[chainName];
216
+ if (chainData && chainData.type === 'evm') {
217
+ chains.push(toCoreChain(chainData));
218
+ }
219
+ });
220
+ }
221
+ // Priority 2: If no specific config, include default chains that might be shown
222
+ // This ensures Base and other common chains are available even if not explicitly configured
223
+ if (chains.length === 0) {
224
+ // Include common chains that are likely to be in availableChains
225
+ chains.push(toCoreChain(EVM_CHAINS.ethereum));
226
+ chains.push(toCoreChain(EVM_CHAINS.polygon));
227
+ chains.push(toCoreChain(EVM_CHAINS.base));
228
+ }
229
+ computedSupportedChains = chains.length > 0 ? chains : [
230
+ toCoreChain(EVM_CHAINS.ethereum),
231
+ toCoreChain(EVM_CHAINS.polygon),
232
+ toCoreChain(EVM_CHAINS.base),
233
+ ];
234
+ }
153
235
  const walletInstance = new AbstraxnWallet({
154
236
  apiKey: config.apiKey,
155
237
  authMethods: config.authMethods,
156
238
  googleClientId: config.googleClientId,
157
- defaultChainId: config.defaultChainId,
158
- supportedChains: config.supportedChains,
239
+ defaultChainId: config.chains?.defaultChainId || config.defaultChainId,
240
+ supportedChains: computedSupportedChains,
159
241
  autoConnect: config.autoConnect ?? false,
160
242
  enableLogging: config.enableLogging ?? false,
161
243
  });
@@ -187,6 +269,24 @@ function AbstraxnProviderInner({ config, children, base, wagmi }) {
187
269
  catch (err) {
188
270
  console.error('Error getting wallet info on connect:', err);
189
271
  }
272
+ // Ensure loading modal is closed when connected (whoami received)
273
+ if (onboardingRef.current) {
274
+ const onboardingAny = onboardingRef.current;
275
+ if (onboardingAny.hideLoadingModal) {
276
+ onboardingAny.hideLoadingModal();
277
+ }
278
+ // Also ensure the overlay is hidden if it was opened
279
+ if (onboardingAny.modalOverlay && onboardingAny.modalOverlay.classList.contains('onboarding-modal-open')) {
280
+ onboardingAny.modalOverlay.classList.remove('onboarding-modal-open');
281
+ onboardingAny.modalOverlay.classList.add('onboarding-modal-closing');
282
+ setTimeout(() => {
283
+ if (onboardingAny.modalOverlay) {
284
+ onboardingAny.modalOverlay.style.display = 'none';
285
+ }
286
+ }, 200);
287
+ document.body.style.overflow = '';
288
+ }
289
+ }
190
290
  });
191
291
  walletInstance.on('disconnect', () => {
192
292
  setIsConnected(false);
@@ -250,7 +350,9 @@ function AbstraxnProviderInner({ config, children, base, wagmi }) {
250
350
  }
251
351
  catch (err) {
252
352
  console.error('OTP Verify Error:', err);
253
- return { success: false };
353
+ // Return the actual error message from the API
354
+ const errorMessage = err instanceof Error ? err.message : 'Failed to verify OTP';
355
+ return { success: false, error: errorMessage };
254
356
  }
255
357
  },
256
358
  onGoogleLogin: async () => {
@@ -294,22 +396,6 @@ function AbstraxnProviderInner({ config, children, base, wagmi }) {
294
396
  onLoginSuccess: async (data) => {
295
397
  // Clear any previous errors on successful login
296
398
  setError(null);
297
- // Hide onboarding UI
298
- if (onboardingRef.current) {
299
- const onboardingAny = onboardingRef.current;
300
- if (onboardingAny.modalOverlay) {
301
- onboardingAny.modalOverlay.classList.remove('onboarding-modal-open');
302
- onboardingAny.modalOverlay.classList.add('onboarding-modal-closing');
303
- setTimeout(() => {
304
- if (onboardingAny.modalOverlay) {
305
- onboardingAny.modalOverlay.style.display = 'none';
306
- }
307
- }, 200);
308
- }
309
- document.body.style.overflow = '';
310
- }
311
- // Set connected state
312
- setIsConnected(true);
313
399
  // Set user if provided in data
314
400
  if (data.user) {
315
401
  setUser(data.user);
@@ -323,9 +409,45 @@ function AbstraxnProviderInner({ config, children, base, wagmi }) {
323
409
  setAddress(addr);
324
410
  const cid = await walletInstance.getChainId();
325
411
  setChainId(cid);
412
+ // Only hide onboarding UI and set connected if whoami succeeds
413
+ if (onboardingRef.current) {
414
+ const onboardingAny = onboardingRef.current;
415
+ if (onboardingAny.hideLoadingModal) {
416
+ onboardingAny.hideLoadingModal();
417
+ }
418
+ if (onboardingAny.modalOverlay) {
419
+ onboardingAny.modalOverlay.classList.remove('onboarding-modal-open');
420
+ onboardingAny.modalOverlay.classList.add('onboarding-modal-closing');
421
+ setTimeout(() => {
422
+ if (onboardingAny.modalOverlay) {
423
+ onboardingAny.modalOverlay.style.display = 'none';
424
+ }
425
+ }, 200);
426
+ }
427
+ document.body.style.overflow = '';
428
+ }
429
+ // Set connected state only after whoami succeeds
430
+ setIsConnected(true);
326
431
  }
327
432
  catch (err) {
328
433
  console.error('Error loading whoami after login:', err);
434
+ // Hide loading modal on whoami error
435
+ if (onboardingRef.current) {
436
+ const onboardingAny = onboardingRef.current;
437
+ if (onboardingAny.hideLoadingModal) {
438
+ onboardingAny.hideLoadingModal();
439
+ }
440
+ // Show error modal/screen
441
+ const errorMessage = err instanceof Error ? err.message : 'Failed to load user information';
442
+ if (onboardingAny.showError) {
443
+ onboardingAny.showError(errorMessage);
444
+ }
445
+ }
446
+ // Set error state
447
+ const error = err instanceof Error ? err : new Error('Failed to load user information after login');
448
+ setError(error);
449
+ // Don't set connected if whoami fails
450
+ setIsConnected(false);
329
451
  }
330
452
  }
331
453
  },
@@ -347,6 +469,20 @@ function AbstraxnProviderInner({ config, children, base, wagmi }) {
347
469
  params.get('error') ||
348
470
  params.get('code') ||
349
471
  params.get('accessToken');
472
+ const getAuthProviderFromToken = (token) => {
473
+ try {
474
+ const base64Url = token.split('.')[1];
475
+ const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
476
+ const jsonPayload = decodeURIComponent(window.atob(base64).split('').map(function (c) {
477
+ return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
478
+ }).join(''));
479
+ const payload = JSON.parse(jsonPayload);
480
+ return (payload.authProvider || payload.provider || '').toLowerCase();
481
+ }
482
+ catch (e) {
483
+ return null;
484
+ }
485
+ };
350
486
  const matchesProvider = (provider, params) => {
351
487
  const providerParam = (params.get('provider') || params.get('authProvider') || '').toLowerCase();
352
488
  const path = window.location.pathname.toLowerCase();
@@ -356,6 +492,17 @@ function AbstraxnProviderInner({ config, children, base, wagmi }) {
356
492
  }
357
493
  return providerParam === provider;
358
494
  }
495
+ // Check accessToken for provider
496
+ const accessToken = params.get('accessToken');
497
+ if (accessToken) {
498
+ const tokenProvider = getAuthProviderFromToken(accessToken);
499
+ if (tokenProvider) {
500
+ if (provider === 'twitter') {
501
+ return tokenProvider === 'twitter' || tokenProvider === 'x';
502
+ }
503
+ return tokenProvider === provider;
504
+ }
505
+ }
359
506
  if (provider === 'twitter') {
360
507
  return path.includes('/twitter') || path.includes('/x');
361
508
  }
@@ -375,12 +522,16 @@ function AbstraxnProviderInner({ config, children, base, wagmi }) {
375
522
  onboardingAny.modalOverlay.style.display = 'none';
376
523
  document.body.style.overflow = '';
377
524
  }
378
- else if (hasSuccess && onboardingAny.modalOverlay) {
379
- // If success=true is in URL, ensure modal is open to show loading
380
- onboardingAny.modalOverlay.classList.remove('onboarding-modal-closing');
381
- onboardingAny.modalOverlay.classList.add('onboarding-modal-open');
382
- onboardingAny.modalOverlay.style.display = 'flex';
383
- document.body.style.overflow = 'hidden';
525
+ else if (hasSuccess) {
526
+ // If success=true is in URL, show loading modal
527
+ // Use setTimeout to ensure onboarding is fully initialized
528
+ setTimeout(() => {
529
+ const onboardingInstance = onboardingRef.current;
530
+ if (onboardingInstance && onboardingInstance.showLoadingModal) {
531
+ // Directly show loading modal - it creates its own overlay with header and footer
532
+ onboardingInstance.showLoadingModal();
533
+ }
534
+ }, 150);
384
535
  }
385
536
  onboardingRef.current = onboarding;
386
537
  // Handle Google OAuth callback (only in useEffect, not exposed)
@@ -420,12 +571,17 @@ function AbstraxnProviderInner({ config, children, base, wagmi }) {
420
571
  }
421
572
  catch (err) {
422
573
  console.error('Google callback error:', err);
423
- // Hide loading modal on error
574
+ // Hide loading modal on error (including whoami API failures)
424
575
  if (onboardingRef.current) {
425
576
  const onboardingAny = onboardingRef.current;
577
+ // Always try to hide loading modal first
426
578
  if (onboardingAny.hideLoadingModal) {
427
579
  onboardingAny.hideLoadingModal();
428
580
  }
581
+ // Also hide any main modal overlay
582
+ if (onboardingAny.modalOverlay) {
583
+ onboardingAny.modalOverlay.style.display = 'none';
584
+ }
429
585
  // Show error modal/screen
430
586
  const errorMessage = err instanceof Error ? err.message : 'Google authentication failed';
431
587
  if (onboardingAny.showError) {
@@ -434,6 +590,8 @@ function AbstraxnProviderInner({ config, children, base, wagmi }) {
434
590
  }
435
591
  setError(err instanceof Error ? err : new Error('Google callback failed'));
436
592
  googleCallbackHandledRef.current = false;
593
+ // Ensure body scroll is restored
594
+ document.body.style.overflow = '';
437
595
  }
438
596
  };
439
597
  const handleDiscordCallback = async () => {
@@ -472,12 +630,17 @@ function AbstraxnProviderInner({ config, children, base, wagmi }) {
472
630
  }
473
631
  catch (err) {
474
632
  console.error('Discord callback error:', err);
475
- // Hide loading modal on error
633
+ // Hide loading modal on error (including whoami API failures)
476
634
  if (onboardingRef.current) {
477
635
  const onboardingAny = onboardingRef.current;
636
+ // Always try to hide loading modal first
478
637
  if (onboardingAny.hideLoadingModal) {
479
638
  onboardingAny.hideLoadingModal();
480
639
  }
640
+ // Also hide any main modal overlay
641
+ if (onboardingAny.modalOverlay) {
642
+ onboardingAny.modalOverlay.style.display = 'none';
643
+ }
481
644
  // Show error modal/screen
482
645
  const errorMessage = err instanceof Error ? err.message : 'Discord authentication failed';
483
646
  if (onboardingAny.showError) {
@@ -486,6 +649,8 @@ function AbstraxnProviderInner({ config, children, base, wagmi }) {
486
649
  }
487
650
  setError(err instanceof Error ? err : new Error('Discord callback failed'));
488
651
  discordCallbackHandledRef.current = false;
652
+ // Ensure body scroll is restored
653
+ document.body.style.overflow = '';
489
654
  }
490
655
  };
491
656
  const handleTwitterCallback = async () => {
@@ -524,12 +689,17 @@ function AbstraxnProviderInner({ config, children, base, wagmi }) {
524
689
  }
525
690
  catch (err) {
526
691
  console.error('Twitter callback error:', err);
527
- // Hide loading modal on error
692
+ // Hide loading modal on error (including whoami API failures)
528
693
  if (onboardingRef.current) {
529
694
  const onboardingAny = onboardingRef.current;
695
+ // Always try to hide loading modal first
530
696
  if (onboardingAny.hideLoadingModal) {
531
697
  onboardingAny.hideLoadingModal();
532
698
  }
699
+ // Also hide any main modal overlay
700
+ if (onboardingAny.modalOverlay) {
701
+ onboardingAny.modalOverlay.style.display = 'none';
702
+ }
533
703
  // Show error modal/screen
534
704
  const errorMessage = err instanceof Error ? err.message : 'Twitter authentication failed';
535
705
  if (onboardingAny.showError) {
@@ -538,6 +708,8 @@ function AbstraxnProviderInner({ config, children, base, wagmi }) {
538
708
  }
539
709
  setError(err instanceof Error ? err : new Error('Twitter callback failed'));
540
710
  twitterCallbackHandledRef.current = false;
711
+ // Ensure body scroll is restored
712
+ document.body.style.overflow = '';
541
713
  }
542
714
  };
543
715
  handleGoogleCallback();
@@ -659,6 +831,10 @@ function AbstraxnProviderInner({ config, children, base, wagmi }) {
659
831
  // Modal already exists, just show it
660
832
  // Use requestAnimationFrame to prevent blinking
661
833
  requestAnimationFrame(() => {
834
+ // Check if we're on OTP screen - if so, ensure social buttons stay hidden
835
+ const isOtpScreen = onboarding.otpVerificationScreen &&
836
+ onboarding.otpVerificationScreen.parentElement &&
837
+ onboarding.otpVerificationScreen.offsetParent !== null;
662
838
  onboarding.modalOverlay.classList.remove('onboarding-modal-closing');
663
839
  onboarding.modalOverlay.classList.add('onboarding-modal-open');
664
840
  onboarding.modalOverlay.style.display = 'flex';
@@ -666,11 +842,39 @@ function AbstraxnProviderInner({ config, children, base, wagmi }) {
666
842
  onboarding.rootElement.style.display = '';
667
843
  }
668
844
  document.body.style.overflow = 'hidden';
845
+ // If on OTP screen, ensure all login elements (social buttons, etc.) are hidden
846
+ if (isOtpScreen) {
847
+ // On OTP screen - ensure all login elements are hidden
848
+ if (onboarding.hideLoginElements && typeof onboarding.hideLoginElements === 'function') {
849
+ onboarding.hideLoginElements();
850
+ }
851
+ else {
852
+ // Fallback: manually hide elements
853
+ if (onboarding.googleButton)
854
+ onboarding.googleButton.style.display = 'none';
855
+ if (onboarding.twitterButton)
856
+ onboarding.twitterButton.style.display = 'none';
857
+ if (onboarding.discordButton)
858
+ onboarding.discordButton.style.display = 'none';
859
+ if (onboarding.socialGrid)
860
+ onboarding.socialGrid.style.display = 'none';
861
+ if (onboarding.divider)
862
+ onboarding.divider.style.display = 'none';
863
+ if (onboarding.passkeyLoginButton)
864
+ onboarding.passkeyLoginButton.style.display = 'none';
865
+ if (onboarding.passkeySignupLink)
866
+ onboarding.passkeySignupLink.style.display = 'none';
867
+ if (onboarding.passkeyDivider)
868
+ onboarding.passkeyDivider.style.display = 'none';
869
+ if (onboarding.externalWalletContainer)
870
+ onboarding.externalWalletContainer.style.display = 'none';
871
+ if (onboarding.externalWalletDivider)
872
+ onboarding.externalWalletDivider.style.display = 'none';
873
+ }
874
+ }
669
875
  // CRITICAL: Always ensure external wallets are mounted when modal reopens
670
876
  if (externalWalletsEnabledRef.current && onboarding.externalWalletContainer) {
671
877
  // Check if we're on OTP screen - if so, don't show external wallets
672
- const isOtpScreen = onboarding.otpVerificationScreen &&
673
- onboarding.otpVerificationScreen.parentElement;
674
878
  if (!isOtpScreen) {
675
879
  // Only show external wallets if not on OTP screen
676
880
  onboarding.externalWalletContainer.style.display = '';
@@ -1248,8 +1452,13 @@ function AbstraxnProviderInner({ config, children, base, wagmi }) {
1248
1452
  if (!externalWalletsEnabled || !wagmiAccount) {
1249
1453
  return;
1250
1454
  }
1251
- // Prevent auto-connect
1252
- if (wagmiAccount.isConnected && !explicitConnectionRef.current && !autoDisconnectHandledRef.current) {
1455
+ // Prevent auto-connect (but allow restoration from persistence)
1456
+ // Only auto-disconnect if:
1457
+ // 1. wagmiAccount is connected
1458
+ // 2. We don't have explicitConnectionRef set (meaning user didn't explicitly connect)
1459
+ // 3. We haven't already handled auto-disconnect
1460
+ // 4. We don't have a stored address (meaning this isn't a restoration from persistence)
1461
+ if (wagmiAccount.isConnected && !explicitConnectionRef.current && !autoDisconnectHandledRef.current && lastAddressRef.current === null) {
1253
1462
  autoDisconnectHandledRef.current = true;
1254
1463
  if (wagmiDisconnect) {
1255
1464
  setTimeout(() => {
@@ -1305,11 +1514,16 @@ function AbstraxnProviderInner({ config, children, base, wagmi }) {
1305
1514
  const addressChanged = lastAddressRef.current !== formattedAddress;
1306
1515
  const chainIdChanged = lastChainIdRef.current !== currentChainId;
1307
1516
  // Also check if we need to reconnect (lastAddressRef is null but wagmiAccount is connected)
1308
- // This handles the case where user disconnects and then reconnects
1517
+ // This handles the case where user disconnects and then reconnects, OR page reload
1309
1518
  const needsReconnect = lastAddressRef.current === null && wagmiAccount.isConnected && formattedAddress;
1310
1519
  // Only update if something actually changed OR if we need to reconnect
1311
1520
  if (addressChanged || chainIdChanged || needsReconnect) {
1312
1521
  isUpdatingRef.current = true;
1522
+ // If this is a restoration (needsReconnect), set explicitConnectionRef to prevent auto-disconnect
1523
+ if (needsReconnect) {
1524
+ explicitConnectionRef.current = true;
1525
+ autoDisconnectHandledRef.current = false;
1526
+ }
1313
1527
  // Update address if it changed or if we need to reconnect
1314
1528
  if (addressChanged || needsReconnect) {
1315
1529
  setIsExternalWalletConnected(true);
@@ -1653,6 +1867,177 @@ function AbstraxnProviderInner({ config, children, base, wagmi }) {
1653
1867
  const currentChainId = isExternalWalletConnected && externalWalletChainId
1654
1868
  ? externalWalletChainId
1655
1869
  : chainId;
1870
+ // Fetch balance for Abstraxn wallet (not external wallet)
1871
+ useEffect(() => {
1872
+ if (isExternalWalletConnected || !address || !currentChainId) {
1873
+ setWalletBalance(null);
1874
+ return;
1875
+ }
1876
+ const fetchBalance = async () => {
1877
+ try {
1878
+ const currentChain = getChainById(currentChainId);
1879
+ if (!currentChain || currentChain.type !== 'evm') {
1880
+ setWalletBalance(null);
1881
+ return;
1882
+ }
1883
+ const publicClient = createPublicClient({
1884
+ chain: {
1885
+ id: currentChain.id,
1886
+ name: currentChain.name,
1887
+ nativeCurrency: currentChain.nativeCurrency,
1888
+ rpcUrls: {
1889
+ default: {
1890
+ http: [currentChain.rpcUrl],
1891
+ },
1892
+ },
1893
+ },
1894
+ transport: http(currentChain.rpcUrl),
1895
+ });
1896
+ const balance = await publicClient.getBalance({
1897
+ address: address,
1898
+ });
1899
+ setWalletBalance(balance);
1900
+ }
1901
+ catch (error) {
1902
+ console.error('Failed to fetch balance:', error);
1903
+ setWalletBalance(null);
1904
+ }
1905
+ };
1906
+ fetchBalance();
1907
+ // Refetch balance every 10 seconds
1908
+ const interval = setInterval(fetchBalance, 10000);
1909
+ return () => clearInterval(interval);
1910
+ }, [address, currentChainId, isExternalWalletConnected]);
1911
+ // Compute available chains from config - supports both legacy and new format
1912
+ const availableChains = useMemo(() => {
1913
+ const chains = [];
1914
+ const chainConfig = config.chains;
1915
+ // Priority 1: Check new chains config format
1916
+ if (chainConfig?.supportedEvmChains && chainConfig.supportedEvmChains.length > 0) {
1917
+ // Use configured chains from new format
1918
+ chainConfig.supportedEvmChains.forEach(chainName => {
1919
+ const chain = EVM_CHAINS[chainName];
1920
+ if (chain) {
1921
+ chains.push(chain);
1922
+ }
1923
+ });
1924
+ }
1925
+ // Priority 2: Check legacy supportedChains format
1926
+ else if (config.supportedChains && config.supportedChains.length > 0) {
1927
+ // Convert legacy Chain format to ChainData
1928
+ config.supportedChains.forEach(legacyChain => {
1929
+ // Try to find matching chain by ID
1930
+ const chainData = getChainById(legacyChain.id);
1931
+ if (chainData) {
1932
+ chains.push(chainData);
1933
+ }
1934
+ else {
1935
+ // If not found, create ChainData from legacy chain
1936
+ const newChain = {
1937
+ id: legacyChain.id,
1938
+ name: legacyChain.name.toLowerCase().replace(/\s+/g, '-'),
1939
+ displayName: legacyChain.name,
1940
+ rpcUrl: legacyChain.rpcUrl,
1941
+ explorerUrl: `https://etherscan.io`, // Default explorer
1942
+ nativeCurrency: legacyChain.nativeCurrency,
1943
+ type: 'evm', // Assume EVM for legacy chains
1944
+ isTestnet: legacyChain.id !== 1 && legacyChain.id !== 137 && legacyChain.id !== 8453, // Common mainnets
1945
+ };
1946
+ chains.push(newChain);
1947
+ }
1948
+ });
1949
+ }
1950
+ // Priority 3: Default chains only if nothing configured at all
1951
+ // Only show defaults if both config.chains and config.supportedChains are missing
1952
+ else if (!chainConfig && !config.supportedChains) {
1953
+ chains.push(EVM_CHAINS.ethereum, EVM_CHAINS.polygon, EVM_CHAINS.base);
1954
+ }
1955
+ // Add Solana chains if enabled (from new config format)
1956
+ if (chainConfig?.enableSolana) {
1957
+ chains.push(SOLANA_CHAINS.solana);
1958
+ }
1959
+ // Remove duplicates by chain ID
1960
+ const uniqueChains = chains.filter((chain, index, self) => index === self.findIndex(c => c.id === chain.id));
1961
+ // Only return defaults if absolutely nothing was configured
1962
+ return uniqueChains.length > 0
1963
+ ? uniqueChains
1964
+ : (!chainConfig && !config.supportedChains
1965
+ ? [EVM_CHAINS.ethereum, EVM_CHAINS.polygon, EVM_CHAINS.base]
1966
+ : []);
1967
+ }, [config.chains, config.supportedChains]);
1968
+ // Get current chain data
1969
+ const currentChain = useMemo(() => {
1970
+ if (!currentChainId)
1971
+ return null;
1972
+ return getChainById(currentChainId) || null;
1973
+ }, [currentChainId]);
1974
+ // Enhanced switchChain that works for both EVM and Solana
1975
+ const switchChainEnhanced = useCallback(async (targetChainId) => {
1976
+ if (!walletRef.current) {
1977
+ throw new Error('Wallet not initialized');
1978
+ }
1979
+ // Check if chain is in availableChains (user-configured chains)
1980
+ const targetChainInAvailable = availableChains?.find(c => c.id === targetChainId);
1981
+ if (!targetChainInAvailable) {
1982
+ throw new Error(`Chain with ID ${targetChainId} is not available. Please configure it in your SDK setup.`);
1983
+ }
1984
+ const targetChain = getChainById(targetChainId);
1985
+ if (!targetChain) {
1986
+ throw new Error(`Chain with ID ${targetChainId} is not supported`);
1987
+ }
1988
+ setLoading(true);
1989
+ setError(null);
1990
+ try {
1991
+ if (targetChain.type === 'evm') {
1992
+ // For EVM chains, use the existing switchChain
1993
+ if (isExternalWalletConnected && wagmiSwitchChain) {
1994
+ // External wallet - use wagmi switchChain
1995
+ await wagmiSwitchChain.switchChainAsync({ chainId: targetChainId });
1996
+ setExternalWalletChainId(targetChainId);
1997
+ }
1998
+ else {
1999
+ // Abstraxn wallet - try to switch, but if chain is not in wallet's supportedChains,
2000
+ // we'll update the state directly (for chains that are in availableChains but not in wallet config)
2001
+ try {
2002
+ await switchChain(targetChainId);
2003
+ }
2004
+ catch (switchErr) {
2005
+ // If the wallet doesn't support this chain, but it's in availableChains,
2006
+ // we can still update the state to allow UI to work
2007
+ if (switchErr?.message?.includes('not supported') && targetChainInAvailable) {
2008
+ // Update chainId state directly for chains in availableChains
2009
+ setChainId(targetChainId);
2010
+ // Emit chainChanged event if wallet supports it
2011
+ if (walletRef.current && typeof walletRef.current.emit === 'function') {
2012
+ walletRef.current.emit('chainChanged', targetChainId);
2013
+ }
2014
+ }
2015
+ else {
2016
+ throw switchErr;
2017
+ }
2018
+ }
2019
+ }
2020
+ }
2021
+ else if (targetChain.type === 'solana') {
2022
+ // For Solana, we might need different handling
2023
+ // For now, just update the chainId state
2024
+ // TODO: Implement actual Solana chain switching when wallet supports it
2025
+ setChainId(targetChainId);
2026
+ }
2027
+ // Update chainId state
2028
+ if (!isExternalWalletConnected) {
2029
+ setChainId(targetChainId);
2030
+ }
2031
+ }
2032
+ catch (err) {
2033
+ const error = err instanceof Error ? err : new Error(`Failed to switch to chain ${targetChainId}: ${err instanceof Error ? err.message : String(err)}`);
2034
+ setError(error);
2035
+ throw error;
2036
+ }
2037
+ finally {
2038
+ setLoading(false);
2039
+ }
2040
+ }, [isExternalWalletConnected, wagmiSwitchChain, switchChain, availableChains]);
1656
2041
  const value = {
1657
2042
  wallet: walletRef.current,
1658
2043
  isInitialized,
@@ -1692,6 +2077,12 @@ function AbstraxnProviderInner({ config, children, base, wagmi }) {
1692
2077
  externalWalletNetwork: externalWalletsEnabled && wagmiChainIdHook ? getNetworkName(wagmiChainIdHook) : undefined,
1693
2078
  availableConnectors: externalWalletsEnabled ? availableConnectors : undefined,
1694
2079
  switchExternalWalletChain: externalWalletsEnabled ? switchExternalWalletChain : undefined,
2080
+ // Chain management
2081
+ switchChainEnhanced,
2082
+ currentChain,
2083
+ availableChains,
2084
+ // Balance (for Abstraxn wallet)
2085
+ walletBalance: !isExternalWalletConnected ? walletBalance : undefined,
1695
2086
  };
1696
2087
  // Ref to store latest value to avoid dependency issues (defined after value)
1697
2088
  const valueRef = useRef(value);
@@ -2160,19 +2551,118 @@ function AbstraxnProviderInner({ config, children, base, wagmi }) {
2160
2551
  }, [value, externalWalletsEnabled]);
2161
2552
  return (_jsx(AbstraxnContext.Provider, { value: value, children: children }));
2162
2553
  }
2554
+ /**
2555
+ * Check if React Query is available and can be used safely
2556
+ * This is a simple check - we can't fully verify React is properly set up
2557
+ * without trying to use it, but we can check if the dependencies exist
2558
+ */
2559
+ function canUseReactQuery() {
2560
+ try {
2561
+ // Check if React is available
2562
+ if (typeof React === 'undefined' || React === null) {
2563
+ return { canUse: false, reason: 'React is not available' };
2564
+ }
2565
+ // Check if React has the version property (indicates it's a valid React object)
2566
+ if (!React.version) {
2567
+ return { canUse: false, reason: 'React version is not available' };
2568
+ }
2569
+ // Check if QueryClientProvider is available
2570
+ if (typeof QueryClientProvider === 'undefined' || QueryClientProvider === null) {
2571
+ return {
2572
+ canUse: false,
2573
+ reason: '@tanstack/react-query is not installed. Please install it: npm install @tanstack/react-query@^5.90.16'
2574
+ };
2575
+ }
2576
+ return { canUse: true };
2577
+ }
2578
+ catch (error) {
2579
+ return { canUse: false, reason: `Error checking React Query: ${error}` };
2580
+ }
2581
+ }
2582
+ /**
2583
+ * Wrapper component that conditionally uses QueryClientProvider
2584
+ * Falls back to rendering children directly if React Query is not available
2585
+ */
2586
+ function QueryClientWrapper({ children, queryClient }) {
2587
+ // Check if we can safely use QueryClientProvider
2588
+ const queryCheck = canUseReactQuery();
2589
+ if (!queryCheck.canUse) {
2590
+ console.error('❌ React Query is not available. External wallets are disabled.\n' +
2591
+ `Reason: ${queryCheck.reason || 'Unknown'}\n` +
2592
+ 'Please install @tanstack/react-query@^5.90.16 and ensure there is only one React instance.');
2593
+ // Return children without QueryClientProvider - external wallets won't work but app won't crash
2594
+ return _jsx(_Fragment, { children: children });
2595
+ }
2596
+ try {
2597
+ return _jsx(QueryClientProvider, { client: queryClient, children: children });
2598
+ }
2599
+ catch (error) {
2600
+ console.error('Failed to render QueryClientProvider:', error);
2601
+ // Fallback: render children without QueryClientProvider
2602
+ return _jsx(_Fragment, { children: children });
2603
+ }
2604
+ }
2163
2605
  /**
2164
2606
  * Main AbstraxnProvider component with optional WagmiProvider wrapper
2165
2607
  */
2608
+ /**
2609
+ * Hook to create QueryClient
2610
+ * Creates a QueryClient instance that's only created once per component instance
2611
+ * Since @tanstack/react-query is now only in peerDependencies, the app's instance will be used
2612
+ * This prevents multiple instances of the package from being bundled
2613
+ */
2614
+ function useQueryClientSafe() {
2615
+ // Create QueryClient using useState to ensure it's only created once
2616
+ // Since @tanstack/react-query is in peerDependencies, this will use the app's instance
2617
+ const [queryClient] = useState(() => {
2618
+ return new QueryClient({
2619
+ defaultOptions: {
2620
+ queries: {
2621
+ refetchOnWindowFocus: false,
2622
+ retry: false,
2623
+ },
2624
+ },
2625
+ });
2626
+ });
2627
+ return queryClient;
2628
+ }
2166
2629
  export function AbstraxnProvider({ config, children }) {
2167
2630
  const externalWalletsEnabled = config.externalWallets?.enabled ?? false;
2631
+ // Get or create QueryClient - tries to use existing one from context first
2632
+ // This ensures we use the app's QueryClient instance if it exists, preventing multiple instances
2633
+ const queryClient = useQueryClientSafe();
2168
2634
  // Create wagmi config if external wallets are enabled
2169
2635
  // Use useMemo to ensure config is created synchronously during render
2170
2636
  // This prevents the "Loading wallet connectors..." state from flashing or blocking initial render
2637
+ // Compute chains for wagmi config (needs to be done before useMemo)
2638
+ const wagmiChains = useMemo(() => {
2639
+ // Use the same logic as availableChains but convert to Core Chain format
2640
+ const chains = [];
2641
+ const chainConfig = config.chains;
2642
+ // Priority 1: Check new chains config format
2643
+ if (chainConfig?.supportedEvmChains && chainConfig.supportedEvmChains.length > 0) {
2644
+ chainConfig.supportedEvmChains.forEach(chainName => {
2645
+ const chainData = EVM_CHAINS[chainName];
2646
+ if (chainData && chainData.type === 'evm') {
2647
+ chains.push(toCoreChain(chainData));
2648
+ }
2649
+ });
2650
+ }
2651
+ // Priority 2: Check legacy supportedChains format
2652
+ else if (config.supportedChains && config.supportedChains.length > 0) {
2653
+ chains.push(...config.supportedChains);
2654
+ }
2655
+ // Priority 3: Default chains
2656
+ else {
2657
+ chains.push(toCoreChain(EVM_CHAINS.ethereum));
2658
+ }
2659
+ return chains.length > 0 ? chains : [toCoreChain(EVM_CHAINS.ethereum)];
2660
+ }, [config.chains, config.supportedChains]);
2171
2661
  const { wagmiConfig, configError } = useMemo(() => {
2172
2662
  if (!externalWalletsEnabled)
2173
2663
  return { wagmiConfig: null, configError: null };
2174
2664
  try {
2175
- const configResult = createWagmiConfig(config.supportedChains, config.externalWallets?.walletConnectProjectId, config.externalWallets?.connectors, config.ui?.theme || 'dark');
2665
+ const configResult = createWagmiConfig(wagmiChains, config.externalWallets?.walletConnectProjectId, config.externalWallets?.connectors, config.ui?.theme || 'dark');
2176
2666
  return { wagmiConfig: configResult, configError: null };
2177
2667
  }
2178
2668
  catch (error) {
@@ -2182,9 +2672,19 @@ export function AbstraxnProvider({ config, children }) {
2182
2672
  configError: error instanceof Error ? error : new Error('Failed to create wagmi config')
2183
2673
  };
2184
2674
  }
2185
- }, [externalWalletsEnabled, config.supportedChains, config.externalWallets?.walletConnectProjectId, config.externalWallets?.connectors]);
2675
+ }, [externalWalletsEnabled, wagmiChains, config.externalWallets?.walletConnectProjectId, config.externalWallets?.connectors]);
2186
2676
  // If external wallets are enabled, wrap with QueryClientProvider and WagmiProvider
2187
2677
  if (externalWalletsEnabled) {
2678
+ // Check if React Query is available BEFORE doing anything else
2679
+ // This prevents errors from happening in the first place
2680
+ const queryCheck = canUseReactQuery();
2681
+ if (!queryCheck.canUse) {
2682
+ console.error('❌ External wallets are disabled because React Query is not available.\n' +
2683
+ `Reason: ${queryCheck.reason || 'Unknown'}\n` +
2684
+ 'Please install @tanstack/react-query@^5.90.16 and ensure there is only one React instance.\n' +
2685
+ 'Falling back to Abstraxn wallet only.');
2686
+ return _jsx(AbstraxnProviderWithoutWagmi, { config: config, children: children });
2687
+ }
2188
2688
  if (configError) {
2189
2689
  console.error('Failed to create wagmi config:', configError);
2190
2690
  // Fallback to provider without wagmi if config creation fails
@@ -2193,9 +2693,9 @@ export function AbstraxnProvider({ config, children }) {
2193
2693
  if (!wagmiConfig) {
2194
2694
  // Show loading state while config is being created
2195
2695
  // Don't render AbstraxnProviderInner until wagmiConfig is ready
2196
- return (_jsx(QueryClientProvider, { client: defaultQueryClient, children: _jsx("div", { style: { display: 'none' }, children: "Loading wallet connectors..." }) }));
2696
+ return (_jsx(QueryClientWrapper, { queryClient: queryClient, children: _jsx("div", { style: { display: 'none' }, children: "Loading wallet connectors..." }) }));
2197
2697
  }
2198
- return (_jsx(QueryClientProvider, { client: defaultQueryClient, children: _jsx(WagmiProvider, { config: wagmiConfig, children: _jsx(AbstraxnProviderWithWagmi, { config: config, children: children }) }) }));
2698
+ return (_jsx(QueryClientWrapper, { queryClient: queryClient, children: _jsx(WagmiProvider, { config: wagmiConfig, children: _jsx(AbstraxnProviderWithWagmi, { config: config, children: children }) }) }));
2199
2699
  }
2200
2700
  // If external wallets are disabled, use the provider without wagmi
2201
2701
  return _jsx(AbstraxnProviderWithoutWagmi, { config: config, children: children });