signer-test-sdk-react 0.0.12 → 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 (75) hide show
  1. package/dist/src/AbstraxnProvider.d.ts +2 -5
  2. package/dist/src/AbstraxnProvider.js +189 -18
  3. package/dist/src/AbstraxnProvider.js.map +1 -1
  4. package/dist/src/WalletModal.css +547 -21
  5. package/dist/src/WalletModal.js +98 -164
  6. package/dist/src/WalletModal.js.map +1 -1
  7. package/dist/src/components/OnboardingUI/OnboardingUIWeb.d.ts +7 -0
  8. package/dist/src/components/OnboardingUI/OnboardingUIWeb.js +169 -20
  9. package/dist/src/components/OnboardingUI/OnboardingUIWeb.js.map +1 -1
  10. package/dist/src/components/WalletModal/components/ChainSelector.css +180 -0
  11. package/dist/src/components/WalletModal/components/ChainSelector.d.ts +10 -0
  12. package/dist/src/components/WalletModal/components/ChainSelector.js +34 -0
  13. package/dist/src/components/WalletModal/components/ChainSelector.js.map +1 -0
  14. package/dist/src/components/WalletModal/components/ExportKeyModal.css +133 -0
  15. package/dist/src/components/WalletModal/components/ExportKeyModal.d.ts +9 -0
  16. package/dist/src/components/WalletModal/components/ExportKeyModal.js +31 -0
  17. package/dist/src/components/WalletModal/components/ExportKeyModal.js.map +1 -0
  18. package/dist/src/components/WalletModal/components/ExportWarningModal.css +2 -0
  19. package/dist/src/components/WalletModal/components/ExportWarningModal.d.ts +11 -0
  20. package/dist/src/components/WalletModal/components/ExportWarningModal.js +18 -0
  21. package/dist/src/components/WalletModal/components/ExportWarningModal.js.map +1 -0
  22. package/dist/src/components/WalletModal/components/ManageWalletModal.css +160 -0
  23. package/dist/src/components/WalletModal/components/ManageWalletModal.d.ts +12 -0
  24. package/dist/src/components/WalletModal/components/ManageWalletModal.js +21 -0
  25. package/dist/src/components/WalletModal/components/ManageWalletModal.js.map +1 -0
  26. package/dist/src/components/WalletModal/components/PreviewTransactionModal.css +128 -0
  27. package/dist/src/components/WalletModal/components/PreviewTransactionModal.d.ts +17 -0
  28. package/dist/src/components/WalletModal/components/PreviewTransactionModal.js +10 -0
  29. package/dist/src/components/WalletModal/components/PreviewTransactionModal.js.map +1 -0
  30. package/dist/src/components/WalletModal/components/ReceiveModal.css +101 -0
  31. package/dist/src/components/WalletModal/components/ReceiveModal.d.ts +8 -0
  32. package/dist/src/components/WalletModal/components/ReceiveModal.js +22 -0
  33. package/dist/src/components/WalletModal/components/ReceiveModal.js.map +1 -0
  34. package/dist/src/components/WalletModal/components/SendModal.css +234 -0
  35. package/dist/src/components/WalletModal/components/SendModal.d.ts +18 -0
  36. package/dist/src/components/WalletModal/components/SendModal.js +127 -0
  37. package/dist/src/components/WalletModal/components/SendModal.js.map +1 -0
  38. package/dist/src/components/WalletModal/components/SuccessModal.css +86 -0
  39. package/dist/src/components/WalletModal/components/SuccessModal.d.ts +13 -0
  40. package/dist/src/components/WalletModal/components/SuccessModal.js +8 -0
  41. package/dist/src/components/WalletModal/components/SuccessModal.js.map +1 -0
  42. package/dist/src/components/WalletModal/components/UserAvatar.d.ts +9 -0
  43. package/dist/src/components/WalletModal/components/UserAvatar.js +31 -0
  44. package/dist/src/components/WalletModal/components/UserAvatar.js.map +1 -0
  45. package/dist/src/components/WalletModal/components/index.d.ts +21 -0
  46. package/dist/src/components/WalletModal/components/index.js +13 -0
  47. package/dist/src/components/WalletModal/components/index.js.map +1 -0
  48. package/dist/src/components/WalletModal/hooks/index.d.ts +6 -0
  49. package/dist/src/components/WalletModal/hooks/index.js +7 -0
  50. package/dist/src/components/WalletModal/hooks/index.js.map +1 -0
  51. package/dist/src/components/WalletModal/hooks/useAddressValidation.d.ts +4 -0
  52. package/dist/src/components/WalletModal/hooks/useAddressValidation.js +17 -0
  53. package/dist/src/components/WalletModal/hooks/useAddressValidation.js.map +1 -0
  54. package/dist/src/components/WalletModal/hooks/useAmountValidation.d.ts +4 -0
  55. package/dist/src/components/WalletModal/hooks/useAmountValidation.js +29 -0
  56. package/dist/src/components/WalletModal/hooks/useAmountValidation.js.map +1 -0
  57. package/dist/src/components/WalletModal/hooks/useSendTransaction.d.ts +20 -0
  58. package/dist/src/components/WalletModal/hooks/useSendTransaction.js +55 -0
  59. package/dist/src/components/WalletModal/hooks/useSendTransaction.js.map +1 -0
  60. package/dist/src/components/WalletModal/index.d.ts +5 -0
  61. package/dist/src/components/WalletModal/index.js +7 -0
  62. package/dist/src/components/WalletModal/index.js.map +1 -0
  63. package/dist/src/components/WalletModal/utils/addressUtils.d.ts +19 -0
  64. package/dist/src/components/WalletModal/utils/addressUtils.js +62 -0
  65. package/dist/src/components/WalletModal/utils/addressUtils.js.map +1 -0
  66. package/dist/src/components/WalletModal/utils/formatUtils.d.ts +20 -0
  67. package/dist/src/components/WalletModal/utils/formatUtils.js +47 -0
  68. package/dist/src/components/WalletModal/utils/formatUtils.js.map +1 -0
  69. package/dist/src/components/WalletModal/utils/index.d.ts +5 -0
  70. package/dist/src/components/WalletModal/utils/index.js +6 -0
  71. package/dist/src/components/WalletModal/utils/index.js.map +1 -0
  72. package/dist/src/wagmiConfig.js +6 -2
  73. package/dist/src/wagmiConfig.js.map +1 -1
  74. package/dist/tsconfig.tsbuildinfo +1 -1
  75. package/package.json +2 -3
@@ -2,16 +2,13 @@
2
2
  * Abstraxn Wallet Provider - React Context Provider
3
3
  * Wrap your app with this provider to use Abstraxn Wallet SDK
4
4
  */
5
- import { type ReactNode } from 'react';
5
+ import React, { type ReactNode } from 'react';
6
6
  import type { AbstraxnProviderConfig, AbstraxnContextValue } from './types';
7
- export declare const AbstraxnContext: import("react").Context<AbstraxnContextValue | null>;
7
+ export declare const AbstraxnContext: React.Context<AbstraxnContextValue | null>;
8
8
  interface AbstraxnProviderProps {
9
9
  config: AbstraxnProviderConfig;
10
10
  children: ReactNode;
11
11
  }
12
- /**
13
- * Main AbstraxnProvider component with optional WagmiProvider wrapper
14
- */
15
12
  export declare function AbstraxnProvider({ config, children }: AbstraxnProviderProps): import("react/jsx-runtime").JSX.Element;
16
13
  /**
17
14
  * Hook to access Abstraxn Wallet context
@@ -1,9 +1,9 @@
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';
@@ -13,15 +13,7 @@ import { parseEther, createPublicClient, http } from 'viem';
13
13
  import { ExternalWalletButtons } from './ExternalWalletButtons';
14
14
  import { EVM_CHAINS, SOLANA_CHAINS, getChainById, toCoreChain } from './chains';
15
15
  export const AbstraxnContext = createContext(null);
16
- // Create a default QueryClient for wagmi
17
- const defaultQueryClient = new QueryClient({
18
- defaultOptions: {
19
- queries: {
20
- refetchOnWindowFocus: false,
21
- retry: false,
22
- },
23
- },
24
- });
16
+ // QueryClient will be created inside the component to ensure React context is available
25
17
  // Base provider logic (shared between with and without wagmi)
26
18
  function useAbstraxnProviderBase(_config) {
27
19
  const [isInitialized, setIsInitialized] = useState(false);
@@ -147,6 +139,58 @@ function AbstraxnProviderInner({ config, children, base, wagmi }) {
147
139
  }
148
140
  });
149
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
150
194
  // Initialize wallet
151
195
  useEffect(() => {
152
196
  // If wallet already exists (from previous mount), reuse it to prevent flicker
@@ -787,6 +831,10 @@ function AbstraxnProviderInner({ config, children, base, wagmi }) {
787
831
  // Modal already exists, just show it
788
832
  // Use requestAnimationFrame to prevent blinking
789
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;
790
838
  onboarding.modalOverlay.classList.remove('onboarding-modal-closing');
791
839
  onboarding.modalOverlay.classList.add('onboarding-modal-open');
792
840
  onboarding.modalOverlay.style.display = 'flex';
@@ -794,11 +842,39 @@ function AbstraxnProviderInner({ config, children, base, wagmi }) {
794
842
  onboarding.rootElement.style.display = '';
795
843
  }
796
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
+ }
797
875
  // CRITICAL: Always ensure external wallets are mounted when modal reopens
798
876
  if (externalWalletsEnabledRef.current && onboarding.externalWalletContainer) {
799
877
  // Check if we're on OTP screen - if so, don't show external wallets
800
- const isOtpScreen = onboarding.otpVerificationScreen &&
801
- onboarding.otpVerificationScreen.parentElement;
802
878
  if (!isOtpScreen) {
803
879
  // Only show external wallets if not on OTP screen
804
880
  onboarding.externalWalletContainer.style.display = '';
@@ -1376,8 +1452,13 @@ function AbstraxnProviderInner({ config, children, base, wagmi }) {
1376
1452
  if (!externalWalletsEnabled || !wagmiAccount) {
1377
1453
  return;
1378
1454
  }
1379
- // Prevent auto-connect
1380
- 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) {
1381
1462
  autoDisconnectHandledRef.current = true;
1382
1463
  if (wagmiDisconnect) {
1383
1464
  setTimeout(() => {
@@ -1433,11 +1514,16 @@ function AbstraxnProviderInner({ config, children, base, wagmi }) {
1433
1514
  const addressChanged = lastAddressRef.current !== formattedAddress;
1434
1515
  const chainIdChanged = lastChainIdRef.current !== currentChainId;
1435
1516
  // Also check if we need to reconnect (lastAddressRef is null but wagmiAccount is connected)
1436
- // This handles the case where user disconnects and then reconnects
1517
+ // This handles the case where user disconnects and then reconnects, OR page reload
1437
1518
  const needsReconnect = lastAddressRef.current === null && wagmiAccount.isConnected && formattedAddress;
1438
1519
  // Only update if something actually changed OR if we need to reconnect
1439
1520
  if (addressChanged || chainIdChanged || needsReconnect) {
1440
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
+ }
1441
1527
  // Update address if it changed or if we need to reconnect
1442
1528
  if (addressChanged || needsReconnect) {
1443
1529
  setIsExternalWalletConnected(true);
@@ -2465,11 +2551,86 @@ function AbstraxnProviderInner({ config, children, base, wagmi }) {
2465
2551
  }, [value, externalWalletsEnabled]);
2466
2552
  return (_jsx(AbstraxnContext.Provider, { value: value, children: children }));
2467
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
+ }
2468
2605
  /**
2469
2606
  * Main AbstraxnProvider component with optional WagmiProvider wrapper
2470
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
+ }
2471
2629
  export function AbstraxnProvider({ config, children }) {
2472
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();
2473
2634
  // Create wagmi config if external wallets are enabled
2474
2635
  // Use useMemo to ensure config is created synchronously during render
2475
2636
  // This prevents the "Loading wallet connectors..." state from flashing or blocking initial render
@@ -2514,6 +2675,16 @@ export function AbstraxnProvider({ config, children }) {
2514
2675
  }, [externalWalletsEnabled, wagmiChains, config.externalWallets?.walletConnectProjectId, config.externalWallets?.connectors]);
2515
2676
  // If external wallets are enabled, wrap with QueryClientProvider and WagmiProvider
2516
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
+ }
2517
2688
  if (configError) {
2518
2689
  console.error('Failed to create wagmi config:', configError);
2519
2690
  // Fallback to provider without wagmi if config creation fails
@@ -2522,9 +2693,9 @@ export function AbstraxnProvider({ config, children }) {
2522
2693
  if (!wagmiConfig) {
2523
2694
  // Show loading state while config is being created
2524
2695
  // Don't render AbstraxnProviderInner until wagmiConfig is ready
2525
- 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..." }) }));
2526
2697
  }
2527
- 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 }) }) }));
2528
2699
  }
2529
2700
  // If external wallets are disabled, use the provider without wagmi
2530
2701
  return _jsx(AbstraxnProviderWithoutWagmi, { config: config, children: children });