signer-test-sdk-react 0.0.22 → 0.0.24

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 (110) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +4 -0
  3. package/dist/src/AbstraxnProvider.d.ts +5 -13
  4. package/dist/src/AbstraxnProvider.js +14 -3126
  5. package/dist/src/AbstraxnProvider.js.map +1 -1
  6. package/dist/src/ConnectButton.css +1 -1
  7. package/dist/src/ExternalWalletButtons.css +1 -1
  8. package/dist/src/ExternalWalletButtons.js +2 -2
  9. package/dist/src/ExternalWalletButtons.js.map +1 -1
  10. package/dist/src/OnboardingUI.d.ts +1 -1
  11. package/dist/src/WalletModal.css +193 -373
  12. package/dist/src/WalletModal.d.ts +1 -1
  13. package/dist/src/WalletModal.js +108 -45
  14. package/dist/src/WalletModal.js.map +1 -1
  15. package/dist/src/chains.d.ts +4 -3
  16. package/dist/src/chains.js +154 -84
  17. package/dist/src/chains.js.map +1 -1
  18. package/dist/src/components/AbstraxnProvider/AbstraxnProvider.d.ts +12 -0
  19. package/dist/src/components/AbstraxnProvider/AbstraxnProvider.js +146 -0
  20. package/dist/src/components/AbstraxnProvider/AbstraxnProvider.js.map +1 -0
  21. package/dist/src/components/AbstraxnProvider/AbstraxnProviderInner.d.ts +25 -0
  22. package/dist/src/components/AbstraxnProvider/AbstraxnProviderInner.js +3086 -0
  23. package/dist/src/components/AbstraxnProvider/AbstraxnProviderInner.js.map +1 -0
  24. package/dist/src/components/AbstraxnProvider/AbstraxnProviderWithWagmi.d.ts +8 -0
  25. package/dist/src/components/AbstraxnProvider/AbstraxnProviderWithWagmi.js +46 -0
  26. package/dist/src/components/AbstraxnProvider/AbstraxnProviderWithWagmi.js.map +1 -0
  27. package/dist/src/components/AbstraxnProvider/AbstraxnProviderWithoutWagmi.d.ts +8 -0
  28. package/dist/src/components/AbstraxnProvider/AbstraxnProviderWithoutWagmi.js +12 -0
  29. package/dist/src/components/AbstraxnProvider/AbstraxnProviderWithoutWagmi.js.map +1 -0
  30. package/dist/src/components/AbstraxnProvider/context.d.ts +2 -0
  31. package/dist/src/components/AbstraxnProvider/context.js +6 -0
  32. package/dist/src/components/AbstraxnProvider/context.js.map +1 -0
  33. package/dist/src/components/AbstraxnProvider/index.d.ts +6 -0
  34. package/dist/src/components/AbstraxnProvider/index.js +7 -0
  35. package/dist/src/components/AbstraxnProvider/index.js.map +1 -0
  36. package/dist/src/components/AbstraxnProvider/useAbstraxnProviderBase.d.ts +30 -0
  37. package/dist/src/components/AbstraxnProvider/useAbstraxnProviderBase.js +49 -0
  38. package/dist/src/components/AbstraxnProvider/useAbstraxnProviderBase.js.map +1 -0
  39. package/dist/src/components/AbstraxnProvider/useAbstraxnWallet.d.ts +2 -0
  40. package/dist/src/components/AbstraxnProvider/useAbstraxnWallet.js +13 -0
  41. package/dist/src/components/AbstraxnProvider/useAbstraxnWallet.js.map +1 -0
  42. package/dist/src/components/AbstraxnProvider/useOAuthCallbacks.d.ts +22 -0
  43. package/dist/src/components/AbstraxnProvider/useOAuthCallbacks.js +242 -0
  44. package/dist/src/components/AbstraxnProvider/useOAuthCallbacks.js.map +1 -0
  45. package/dist/src/components/AbstraxnProvider/useWalletInitialization.d.ts +25 -0
  46. package/dist/src/components/AbstraxnProvider/useWalletInitialization.js +539 -0
  47. package/dist/src/components/AbstraxnProvider/useWalletInitialization.js.map +1 -0
  48. package/dist/src/components/AbstraxnProvider/utils.d.ts +41 -0
  49. package/dist/src/components/AbstraxnProvider/utils.js +139 -0
  50. package/dist/src/components/AbstraxnProvider/utils.js.map +1 -0
  51. package/dist/src/components/OnboardingUI/OnboardingUI.css +8 -5
  52. package/dist/src/components/OnboardingUI/OnboardingUIReact.d.ts +1 -1
  53. package/dist/src/components/OnboardingUI/OnboardingUIWeb.d.ts +1 -1
  54. package/dist/src/components/OnboardingUI/OnboardingUIWeb.js +7 -1
  55. package/dist/src/components/OnboardingUI/OnboardingUIWeb.js.map +1 -1
  56. package/dist/src/components/OnboardingUI/components/EmailForm.d.ts +1 -1
  57. package/dist/src/components/OnboardingUI/components/EmailForm.js +1 -1
  58. package/dist/src/components/OnboardingUI/components/EmailForm.js.map +1 -1
  59. package/dist/src/components/OnboardingUI/components/OtpForm.d.ts +1 -1
  60. package/dist/src/components/OnboardingUI/components/PasskeyButton.d.ts +1 -1
  61. package/dist/src/components/OnboardingUI/components/SocialButtons.d.ts +1 -1
  62. package/dist/src/components/OnboardingUI/hooks/useAuthMethods.d.ts +1 -1
  63. package/dist/src/components/OnboardingUI/hooks/useOnboarding.d.ts +1 -1
  64. package/dist/src/components/OnboardingUI/index.d.ts +1 -1
  65. package/dist/src/components/WalletModal/components/ChainSelector.css +249 -102
  66. package/dist/src/components/WalletModal/components/ChainSelector.d.ts +7 -6
  67. package/dist/src/components/WalletModal/components/ChainSelector.js +68 -27
  68. package/dist/src/components/WalletModal/components/ChainSelector.js.map +1 -1
  69. package/dist/src/components/WalletModal/components/ExportKeyModal.css +89 -88
  70. package/dist/src/components/WalletModal/components/ExportKeyModal.d.ts +6 -1
  71. package/dist/src/components/WalletModal/components/ExportKeyModal.js +6 -11
  72. package/dist/src/components/WalletModal/components/ExportKeyModal.js.map +1 -1
  73. package/dist/src/components/WalletModal/components/ExportWarningModal.css +107 -2
  74. package/dist/src/components/WalletModal/components/ExportWarningModal.d.ts +7 -1
  75. package/dist/src/components/WalletModal/components/ExportWarningModal.js +5 -3
  76. package/dist/src/components/WalletModal/components/ExportWarningModal.js.map +1 -1
  77. package/dist/src/components/WalletModal/components/ManageWalletModal.css +90 -4
  78. package/dist/src/components/WalletModal/components/ManageWalletModal.d.ts +3 -3
  79. package/dist/src/components/WalletModal/components/ManageWalletModal.js +28 -13
  80. package/dist/src/components/WalletModal/components/ManageWalletModal.js.map +1 -1
  81. package/dist/src/components/WalletModal/components/PreviewTransactionModal.css +3 -4
  82. package/dist/src/components/WalletModal/components/ReceiveModal.css +93 -58
  83. package/dist/src/components/WalletModal/components/ReceiveModal.js +1 -1
  84. package/dist/src/components/WalletModal/components/ReceiveModal.js.map +1 -1
  85. package/dist/src/components/WalletModal/components/SendModal.css +170 -127
  86. package/dist/src/components/WalletModal/components/SendModal.d.ts +4 -6
  87. package/dist/src/components/WalletModal/components/SendModal.js +131 -39
  88. package/dist/src/components/WalletModal/components/SendModal.js.map +1 -1
  89. package/dist/src/components/WalletModal/components/SuccessModal.css +7 -8
  90. package/dist/src/components/WalletModal/components/TokenSelectorModal.css +240 -0
  91. package/dist/src/components/WalletModal/components/TokenSelectorModal.d.ts +21 -0
  92. package/dist/src/components/WalletModal/components/TokenSelectorModal.js +44 -0
  93. package/dist/src/components/WalletModal/components/TokenSelectorModal.js.map +1 -0
  94. package/dist/src/components/WalletModal/components/UserAvatar.d.ts +1 -1
  95. package/dist/src/components/WalletModal/components/index.d.ts +2 -0
  96. package/dist/src/components/WalletModal/components/index.js +1 -0
  97. package/dist/src/components/WalletModal/components/index.js.map +1 -1
  98. package/dist/src/components/WalletModal/hooks/useSendTransaction.d.ts +1 -1
  99. package/dist/src/hooks.d.ts +402 -362
  100. package/dist/src/hooks.js +486 -244
  101. package/dist/src/hooks.js.map +1 -1
  102. package/dist/src/index.d.ts +1 -1
  103. package/dist/src/index.js +1 -1
  104. package/dist/src/index.js.map +1 -1
  105. package/dist/src/types.d.ts +6 -6
  106. package/dist/src/wagmiConfig.d.ts +2 -2
  107. package/dist/src/wagmiConfig.js +34 -21
  108. package/dist/src/wagmiConfig.js.map +1 -1
  109. package/dist/tsconfig.tsbuildinfo +1 -1
  110. package/package.json +5 -4
package/dist/src/hooks.js CHANGED
@@ -3,10 +3,11 @@
3
3
  */
4
4
  import { useState, useCallback, useEffect, useMemo } from 'react';
5
5
  import { useAbstraxnWallet } from './AbstraxnProvider';
6
- import { createPublicClient, createWalletClient, http, getContract, serializeTransaction, parseEther, encodeFunctionData } from 'viem';
7
- import { useWalletClient as useWagmiWalletClient, useAccount, useConfig, useChainId as useWagmiChainId } from 'wagmi';
6
+ import { createPublicClient, createWalletClient, http, getContract, serializeTransaction, encodeFunctionData } from 'viem';
7
+ import { useWalletClient as useWagmiWalletClient, useAccount, useConfig, useChainId as useWagmiChainId, useSwitchChain as useWagmiSwitchChain, useSignMessage as useWagmiSignMessage } from 'wagmi';
8
8
  import { getWalletClient, switchChain } from '@wagmi/core';
9
9
  import { getConnectorMeta } from './connectors';
10
+ import { getChainById } from './chains';
10
11
  /**
11
12
  * Hook to check if wallet is connected
12
13
  */
@@ -25,7 +26,7 @@ export function useAddress() {
25
26
  * Hook to get current user and whoami information
26
27
  * Returns an object with both user and whoami data
27
28
  */
28
- export function useUser() {
29
+ export function useAuthContext() {
29
30
  const { user, whoami } = useAbstraxnWallet();
30
31
  return { user, whoami };
31
32
  }
@@ -36,20 +37,6 @@ export function useChainId() {
36
37
  const { chainId } = useAbstraxnWallet();
37
38
  return chainId;
38
39
  }
39
- /**
40
- * Hook to check if wallet is initialized
41
- */
42
- export function useIsInitialized() {
43
- const { isInitialized } = useAbstraxnWallet();
44
- return isInitialized;
45
- }
46
- /**
47
- * Hook to get loading state
48
- */
49
- export function useLoading() {
50
- const { loading } = useAbstraxnWallet();
51
- return loading;
52
- }
53
40
  /**
54
41
  * Hook to get error state
55
42
  */
@@ -66,91 +53,6 @@ export function useWallet() {
66
53
  const { wallet } = useAbstraxnWallet();
67
54
  return wallet;
68
55
  }
69
- /**
70
- * Hook to prepare and sign transaction
71
- * Prepares the unsigned transaction, calls the sign API, and returns the signed transaction
72
- * User can execute this signed transaction themselves
73
- */
74
- export function usePrepareTransaction() {
75
- const { wallet, isConnected, address, signTransactionViaAPI } = useAbstraxnWallet();
76
- const prepareTransaction = async (to, value, rpcUrl, chainId) => {
77
- if (!isConnected || !wallet || !address) {
78
- throw new Error('Wallet is not connected');
79
- }
80
- // Import viem functions dynamically
81
- const { createPublicClient, http, serializeTransaction } = await import('viem');
82
- const { polygonAmoy } = await import('viem/chains');
83
- const targetRpcUrl = rpcUrl || 'https://rpc-amoy.polygon.technology';
84
- const targetChainId = chainId || polygonAmoy.id;
85
- // Create public client
86
- const publicClient = createPublicClient({
87
- chain: polygonAmoy,
88
- transport: http(targetRpcUrl),
89
- });
90
- // Get nonce
91
- const nonce = await publicClient.getTransactionCount({ address: address });
92
- // Get gas price
93
- const gasPrice = await publicClient.getGasPrice();
94
- // Convert amount to wei (18 decimals)
95
- const valueInWei = BigInt(Math.floor(Number(value) * 10 ** 18));
96
- // Create unsigned transaction
97
- const unsignedTx = {
98
- to: to,
99
- value: valueInWei,
100
- gas: 21000n,
101
- nonce: nonce,
102
- gasPrice: gasPrice,
103
- chainId: targetChainId,
104
- data: '0x',
105
- };
106
- // Serialize transaction
107
- const serializedTx = serializeTransaction(unsignedTx);
108
- // Sign transaction via API
109
- const signResult = await signTransactionViaAPI(serializedTx, address);
110
- return {
111
- unsignedTransaction: serializedTx,
112
- signedTransaction: signResult.signedTransaction,
113
- };
114
- };
115
- return { prepareTransaction, isConnected, address };
116
- }
117
- /**
118
- * Hook to sign transaction via API
119
- * Returns the signed transaction that user can execute themselves
120
- */
121
- export function useSignTransaction() {
122
- const { wallet, isConnected, address, signTransactionViaAPI } = useAbstraxnWallet();
123
- const signTransaction = async (unsignedTransaction, fromAddress) => {
124
- if (!isConnected || !wallet) {
125
- throw new Error('Wallet is not connected');
126
- }
127
- const targetAddress = fromAddress || address;
128
- if (!targetAddress) {
129
- throw new Error('Address is required');
130
- }
131
- return await signTransactionViaAPI(unsignedTransaction, targetAddress);
132
- };
133
- return { signTransaction, isConnected, address };
134
- }
135
- /**
136
- * Hook to sign and send transaction
137
- * Signs transaction via API and then executes it internally
138
- * Returns transaction hash
139
- */
140
- export function useSignAndSendTransaction() {
141
- const { wallet, isConnected, address, signAndSendTransaction } = useAbstraxnWallet();
142
- const signAndSend = async (unsignedTransaction, fromAddress, rpcUrl) => {
143
- if (!isConnected || !wallet) {
144
- throw new Error('Wallet is not connected');
145
- }
146
- const targetAddress = fromAddress || address;
147
- if (!targetAddress) {
148
- throw new Error('Address is required');
149
- }
150
- return await signAndSendTransaction(unsignedTransaction, targetAddress, rpcUrl);
151
- };
152
- return { signAndSendTransaction: signAndSend, isConnected, address };
153
- }
154
56
  /**
155
57
  * Hook to export wallet private key
156
58
  * Returns the export bundle containing the private key
@@ -405,7 +307,7 @@ export function useExternalWalletInfo() {
405
307
  *
406
308
  * @example
407
309
  * ```tsx
408
- * import { usePublicClient } from 'signer-test-sdk-react';
310
+ * import { usePublicClient } from '@abstraxn/signer-react';
409
311
  * import { polygonAmoy } from 'viem/chains';
410
312
  *
411
313
  * function MyComponent() {
@@ -448,7 +350,7 @@ export function usePublicClient(chain, rpcUrl) {
448
350
  *
449
351
  * @example
450
352
  * ```tsx
451
- * import { useWalletClient } from 'signer-test-sdk-react';
353
+ * import { useWalletClient } from '@abstraxn/signer-react';
452
354
  * import { polygonAmoy } from 'viem/chains';
453
355
  *
454
356
  * function MyComponent() {
@@ -504,7 +406,7 @@ export function useWalletClient(chain, rpcUrl) {
504
406
  *
505
407
  * @example
506
408
  * ```tsx
507
- * import { useContract, usePublicClient } from 'signer-test-sdk-react';
409
+ * import { useContract, usePublicClient } from '@abstraxn/signer-react';
508
410
  * import { polygonAmoy } from 'viem/chains';
509
411
  * import erc20Abi from './erc20Abi.json';
510
412
  *
@@ -608,21 +510,11 @@ export function usePrepareRawTxn(provider) {
608
510
  // Determine if this is a native transfer
609
511
  const isNativeTransfer = !needsEncoding && !hasPreEncodedData;
610
512
  if (isNativeTransfer) {
611
- // Native transfer: convert value to wei and set data to '0x'
612
- if (!value || value === '0' || value === 0) {
513
+ // Native transfer: pass value through as-is (no hex conversion)
514
+ if (value === undefined || value === null || value === '' || value === '0' || value === 0) {
613
515
  throw new Error('Value is required for native transfer');
614
516
  }
615
- // Convert value to wei
616
- const valueStr = typeof value === 'string' ? value.trim() : String(value);
617
- let valueInWei;
618
- try {
619
- valueInWei = parseEther(valueStr);
620
- }
621
- catch (error) {
622
- throw new Error(`Invalid value format: "${valueStr}". Value must be a valid number string (e.g., "0.001").`);
623
- }
624
- // Convert to hex string
625
- finalValue = `0x${valueInWei.toString(16)}`;
517
+ finalValue = typeof value === 'bigint' ? value : (typeof value === 'string' ? value.trim() : String(value));
626
518
  finalData = '0x';
627
519
  }
628
520
  else {
@@ -635,36 +527,8 @@ export function usePrepareRawTxn(provider) {
635
527
  if (!functionName) {
636
528
  throw new Error('Function name is required for encoding function data');
637
529
  }
638
- // Process args to convert ETH amounts to wei for transfer functions
639
- const processedArgs = (args || []).map((arg, index) => {
640
- // Check if this is likely an amount parameter for transfer/transferFrom functions
641
- const isAmountParam = (functionName === 'transfer' || functionName === 'transferFrom') && index === 1;
642
- if (isAmountParam) {
643
- // If arg is a string or number that looks like ETH (has decimal point)
644
- if (typeof arg === 'string' && arg.includes('.')) {
645
- try {
646
- // Convert ETH to wei
647
- const weiAmount = parseEther(arg);
648
- return weiAmount.toString();
649
- }
650
- catch (error) {
651
- throw new Error(`Failed to convert amount "${arg}" to wei. Make sure it's a valid number string (e.g., "0.001").`);
652
- }
653
- }
654
- else if (typeof arg === 'number' && arg % 1 !== 0) {
655
- // Number with decimal places - convert to wei
656
- try {
657
- const weiAmount = parseEther(arg.toString());
658
- return weiAmount.toString();
659
- }
660
- catch (error) {
661
- throw new Error(`Failed to convert amount ${arg} to wei. Make sure it's a valid number.`);
662
- }
663
- }
664
- }
665
- // For other args, just return as-is
666
- return arg;
667
- });
530
+ // Pass args through as-is (no conversion); caller must pass amounts in wei / correct format
531
+ const processedArgs = args ?? [];
668
532
  try {
669
533
  finalData = encodeFunctionData({
670
534
  abi: abi,
@@ -686,18 +550,9 @@ export function usePrepareRawTxn(provider) {
686
550
  else {
687
551
  throw new Error('Either provide encoded data, or provide abi/functionName/args for encoding.');
688
552
  }
689
- // Handle value for contract calls
553
+ // Handle value for contract calls: pass through as-is (no hex conversion)
690
554
  if (value && value !== '0' && value !== 0) {
691
- // Convert value to wei if provided
692
- const valueStr = typeof value === 'string' ? value.trim() : String(value);
693
- let valueInWei;
694
- try {
695
- valueInWei = parseEther(valueStr);
696
- }
697
- catch (error) {
698
- throw new Error(`Invalid value format: "${valueStr}". Value must be a valid number string (e.g., "0.001").`);
699
- }
700
- finalValue = `0x${valueInWei.toString(16)}`;
555
+ finalValue = typeof value === 'bigint' ? value : (typeof value === 'string' ? value.trim() : String(value));
701
556
  }
702
557
  else {
703
558
  finalValue = '0x0';
@@ -724,22 +579,108 @@ export function usePrepareRawTxn(provider) {
724
579
  * const { signTxn } = useSignTxn(publicClient);
725
580
  *
726
581
  * // Prepare transaction
727
- * const rawTx = await prepareRawTxn({
728
- * from: address!,
729
- * to: '0x...',
730
- * value: '0.001',
731
- * });
732
- *
733
- * // Sign transaction
582
+ * const rawTx = await prepareRawTxn({ from: address!, to: '0x...', value: '0.001' });
583
+ * const { estimateGas } = useEstimateGas(publicClient);
584
+ * const { getGasPrice } = useGetGasPrice(publicClient);
585
+ * const { gasLimit } = await estimateGas({ account: address!, to: rawTx.to, data: rawTx.data, value: rawTx.value });
586
+ * const fees = await getGasPrice();
734
587
  * const signedTx = await signTxn({
735
588
  * from: address!,
736
- * ...rawTx, // Spread to, value, data from prepareRawTxn
589
+ * ...rawTx,
590
+ * gas: { gasLimit, maxFeePerGas: fees.maxFeePerGas!, maxPriorityFeePerGas: fees.maxPriorityFeePerGas! },
737
591
  * });
738
592
  * ```
739
593
  */
594
+ // export function useSignTxn(provider: PublicClient) {
595
+ // const { wallet, isConnected, address, signTransactionViaAPI } = useAbstraxnWallet();
596
+ // const signTxn = useCallback(async ({
597
+ // from,
598
+ // to,
599
+ // value,
600
+ // data,
601
+ // chainId,
602
+ // gas,
603
+ // }: {
604
+ // from: Address;
605
+ // to: Address;
606
+ // value: string | bigint;
607
+ // data: `0x${string}`;
608
+ // chainId?: number;
609
+ // /** Gas: pass gasLimit + (maxFeePerGas & maxPriorityFeePerGas for EIP-1559) or (gasPrice for legacy). Use useEstimateGas and useGetGasPrice. */
610
+ // gas: {
611
+ // gasLimit: bigint;
612
+ // gasPrice?: bigint;
613
+ // maxFeePerGas?: bigint;
614
+ // maxPriorityFeePerGas?: bigint;
615
+ // };
616
+ // }) => {
617
+ // if (!isConnected || !wallet) {
618
+ // throw new Error('Wallet is not connected');
619
+ // }
620
+ // if (!provider) {
621
+ // throw new Error('Provider (publicClient) is required');
622
+ // }
623
+ // if (!from) {
624
+ // throw new Error('From address is required');
625
+ // }
626
+ // if (!to) {
627
+ // throw new Error('To address is required');
628
+ // }
629
+ // if (gas.gasLimit === undefined) {
630
+ // throw new Error('gas.gasLimit is required. Use useEstimateGas to get values.');
631
+ // }
632
+ // const isLegacy = gas.gasPrice !== undefined;
633
+ // if (!isLegacy) {
634
+ // if (gas.maxFeePerGas === undefined || gas.maxPriorityFeePerGas === undefined) {
635
+ // throw new Error('gas.maxFeePerGas and gas.maxPriorityFeePerGas are required for EIP-1559, or pass gas.gasPrice for legacy.');
636
+ // }
637
+ // }
638
+ // // Get chain ID from provider or use provided one
639
+ // const targetChainId = chainId || provider.chain?.id;
640
+ // if (!targetChainId) {
641
+ // throw new Error('Chain ID is required. Either provide it or ensure provider has a chain configured.');
642
+ // }
643
+ // // Get nonce
644
+ // const nonce = await provider.getTransactionCount({ address: from });
645
+ // // Value in wei (pass-through from prepareRawTxn, no hex conversion)
646
+ // const valueInWei = typeof value === 'bigint' ? value : BigInt(value === '0x' || value === '' ? '0' : value);
647
+ // // Build unsigned tx from user gas (no estimation in hook)
648
+ // const unsignedTx = isLegacy
649
+ // ? {
650
+ // chainId: targetChainId,
651
+ // from,
652
+ // to,
653
+ // data,
654
+ // value: valueInWei,
655
+ // nonce,
656
+ // gas: gas.gasLimit,
657
+ // gasPrice: gas.gasPrice,
658
+ // }
659
+ // : {
660
+ // chainId: targetChainId,
661
+ // from,
662
+ // to,
663
+ // data,
664
+ // value: valueInWei,
665
+ // nonce,
666
+ // gas: gas.gasLimit,
667
+ // maxFeePerGas: gas.maxFeePerGas!,
668
+ // maxPriorityFeePerGas: gas.maxPriorityFeePerGas!,
669
+ // };
670
+ // // Serialize transaction
671
+ // const serializedTx = serializeTransaction(unsignedTx);
672
+ // // Sign transaction via Turnkey API
673
+ // const signResult = await signTransactionViaAPI(serializedTx, from);
674
+ // return {
675
+ // unsignedTransaction: serializedTx,
676
+ // signedTransaction: signResult.signedTransaction,
677
+ // };
678
+ // }, [provider, isConnected, wallet, address, signTransactionViaAPI]);
679
+ // return { signTxn, isConnected, address };
680
+ // }
740
681
  export function useSignTxn(provider) {
741
682
  const { wallet, isConnected, address, signTransactionViaAPI } = useAbstraxnWallet();
742
- const signTxn = useCallback(async ({ from, to, value, data, chainId, }) => {
683
+ const signTxn = useCallback(async ({ from, to, value, data, chainId, gas, }) => {
743
684
  if (!isConnected || !wallet) {
744
685
  throw new Error('Wallet is not connected');
745
686
  }
@@ -759,32 +700,31 @@ export function useSignTxn(provider) {
759
700
  }
760
701
  // Get nonce
761
702
  const nonce = await provider.getTransactionCount({ address: from });
762
- // Convert hex value to bigint
763
- // Handle empty hex string "0x" by converting to "0x0"
764
- const normalizedValue = value === '0x' ? '0x0' : value;
765
- const valueInWei = BigInt(normalizedValue);
766
- // Estimate gas
767
- const gas = await provider.estimateGas({
768
- account: from,
769
- to,
770
- data,
771
- value: valueInWei,
772
- });
773
- // Estimate fees
774
- const fee = await provider.estimateFeesPerGas();
775
- // Create unsigned transaction
776
- const unsignedTx = {
703
+ // Value in wei (pass-through from prepareRawTxn, no hex conversion)
704
+ const valueInWei = typeof value === 'bigint' ? value : BigInt(value === '0x' || value === '' ? '0' : value);
705
+ // Build base transaction object
706
+ const baseTx = {
777
707
  chainId: targetChainId,
778
708
  from,
779
709
  to,
780
710
  data,
781
711
  value: valueInWei,
782
712
  nonce,
783
- gas,
784
- maxFeePerGas: fee.maxFeePerGas,
785
- maxPriorityFeePerGas: fee.maxPriorityFeePerGas,
786
- type: 'eip1559',
787
713
  };
714
+ // Add gas properties if they exist
715
+ const unsignedTx = { ...baseTx };
716
+ if (gas?.gasLimit !== undefined) {
717
+ unsignedTx.gas = gas.gasLimit;
718
+ }
719
+ if (gas?.gasPrice !== undefined) {
720
+ unsignedTx.gasPrice = gas.gasPrice;
721
+ }
722
+ if (gas?.maxFeePerGas !== undefined) {
723
+ unsignedTx.maxFeePerGas = gas.maxFeePerGas;
724
+ }
725
+ if (gas?.maxPriorityFeePerGas !== undefined) {
726
+ unsignedTx.maxPriorityFeePerGas = gas.maxPriorityFeePerGas;
727
+ }
788
728
  // Serialize transaction
789
729
  const serializedTx = serializeTransaction(unsignedTx);
790
730
  // Sign transaction via Turnkey API
@@ -809,24 +749,114 @@ export function useSignTxn(provider) {
809
749
  * const { signAndSendTxn } = useSignAndSendTxn(publicClient);
810
750
  *
811
751
  * // Prepare transaction
812
- * const rawTx = await prepareRawTxn({
813
- * from: address!,
814
- * to: '0x...',
815
- * value: '0.001',
816
- * });
817
- *
818
- * // Sign and send transaction
752
+ * const rawTx = await prepareRawTxn({ from: address!, to: '0x...', value: '0.001' });
753
+ * const { estimateGas } = useEstimateGas(publicClient);
754
+ * const { getGasPrice } = useGetGasPrice(publicClient);
755
+ * const { gasLimit } = await estimateGas({ account: address!, to: rawTx.to, data: rawTx.data, value: rawTx.value });
756
+ * const fees = await getGasPrice();
819
757
  * const result = await signAndSendTxn({
820
758
  * from: address!,
821
- * ...rawTx, // Spread to, value, data from prepareRawTxn
759
+ * ...rawTx,
760
+ * gas: { gasLimit, maxFeePerGas: fees.maxFeePerGas!, maxPriorityFeePerGas: fees.maxPriorityFeePerGas! },
822
761
  * });
823
- *
824
762
  * console.log('Transaction hash:', result.hash);
825
763
  * ```
826
764
  */
765
+ // export function useSignAndSendTxn(provider: PublicClient) {
766
+ // const { wallet, isConnected, address, signTransactionViaAPI } = useAbstraxnWallet();
767
+ // const signAndSendTxn = useCallback(async ({
768
+ // from,
769
+ // to,
770
+ // value,
771
+ // data,
772
+ // chainId,
773
+ // gas,
774
+ // }: {
775
+ // from: Address;
776
+ // to: Address;
777
+ // value: string | bigint;
778
+ // data: `0x${string}`;
779
+ // chainId?: number;
780
+ // /** Gas: pass gasLimit + (maxFeePerGas & maxPriorityFeePerGas for EIP-1559) or (gasPrice for legacy). Use useEstimateGas and useGetGasPrice. */
781
+ // gas: {
782
+ // gasLimit: bigint;
783
+ // gasPrice?: bigint;
784
+ // maxFeePerGas?: bigint;
785
+ // maxPriorityFeePerGas?: bigint;
786
+ // };
787
+ // }) => {
788
+ // if (!isConnected || !wallet) {
789
+ // throw new Error('Wallet is not connected');
790
+ // }
791
+ // if (!provider) {
792
+ // throw new Error('Provider (publicClient) is required');
793
+ // }
794
+ // if (!from) {
795
+ // throw new Error('From address is required');
796
+ // }
797
+ // if (!to) {
798
+ // throw new Error('To address is required');
799
+ // }
800
+ // if (gas.gasLimit === undefined) {
801
+ // throw new Error('gas.gasLimit is required. Use useEstimateGas to get values.');
802
+ // }
803
+ // const isLegacy = gas.gasPrice !== undefined;
804
+ // if (!isLegacy) {
805
+ // if (gas.maxFeePerGas === undefined || gas.maxPriorityFeePerGas === undefined) {
806
+ // throw new Error('gas.maxFeePerGas and gas.maxPriorityFeePerGas are required for EIP-1559, or pass gas.gasPrice for legacy.');
807
+ // }
808
+ // }
809
+ // // Get chain ID from provider or use provided one
810
+ // const targetChainId = chainId || provider.chain?.id;
811
+ // if (!targetChainId) {
812
+ // throw new Error('Chain ID is required. Either provide it or ensure provider has a chain configured.');
813
+ // }
814
+ // // Get nonce
815
+ // const nonce = await provider.getTransactionCount({ address: from });
816
+ // // Value in wei (pass-through from prepareRawTxn, no hex conversion)
817
+ // const valueInWei = typeof value === 'bigint' ? value : BigInt(value === '0x' || value === '' ? '0' : value);
818
+ // // Build unsigned tx from user gas (no estimation in hook)
819
+ // const unsignedTx = isLegacy
820
+ // ? {
821
+ // chainId: targetChainId,
822
+ // from,
823
+ // to,
824
+ // data,
825
+ // value: valueInWei,
826
+ // nonce,
827
+ // gas: gas.gasLimit,
828
+ // gasPrice: gas.gasPrice,
829
+ // }
830
+ // : {
831
+ // chainId: targetChainId,
832
+ // from,
833
+ // to,
834
+ // data,
835
+ // value: valueInWei,
836
+ // nonce,
837
+ // gas: gas.gasLimit,
838
+ // maxFeePerGas: gas.maxFeePerGas!,
839
+ // maxPriorityFeePerGas: gas.maxPriorityFeePerGas!,
840
+ // };
841
+ // // Serialize transaction
842
+ // const serializedTx = serializeTransaction(unsignedTx);
843
+ // // Sign transaction via Turnkey API
844
+ // const signResult = await signTransactionViaAPI(serializedTx, from);
845
+ // // Send the signed transaction
846
+ // const hash = await provider.sendRawTransaction({
847
+ // serializedTransaction: signResult.signedTransaction as `0x${string}`,
848
+ // });
849
+ // return {
850
+ // hash,
851
+ // unsignedTransaction: serializedTx,
852
+ // signedTransaction: signResult.signedTransaction,
853
+ // };
854
+ // }, [provider, isConnected, wallet, address, signTransactionViaAPI]);
855
+ // return { signAndSendTxn, isConnected, address };
856
+ // }
827
857
  export function useSignAndSendTxn(provider) {
828
858
  const { wallet, isConnected, address, signTransactionViaAPI } = useAbstraxnWallet();
829
- const signAndSendTxn = useCallback(async ({ from, to, value, data, chainId, }) => {
859
+ const signAndSendTxn = useCallback(async ({ from, to, value, data, chainId, gas, }) => {
830
860
  if (!isConnected || !wallet) {
831
861
  throw new Error('Wallet is not connected');
832
862
  }
@@ -846,32 +876,31 @@ export function useSignAndSendTxn(provider) {
846
876
  }
847
877
  // Get nonce
848
878
  const nonce = await provider.getTransactionCount({ address: from });
849
- // Convert hex value to bigint
850
- // Handle empty hex string "0x" by converting to "0x0"
851
- const normalizedValue = value === '0x' ? '0x0' : value;
852
- const valueInWei = BigInt(normalizedValue);
853
- // Estimate gas
854
- const gas = await provider.estimateGas({
855
- account: from,
856
- to,
857
- data,
858
- value: valueInWei,
859
- });
860
- // Estimate fees
861
- const fee = await provider.estimateFeesPerGas();
862
- // Create unsigned transaction
863
- const unsignedTx = {
879
+ // Value in wei (pass-through from prepareRawTxn, no hex conversion)
880
+ const valueInWei = typeof value === 'bigint' ? value : BigInt(value === '0x' || value === '' ? '0' : value);
881
+ // Build base transaction object
882
+ const baseTx = {
864
883
  chainId: targetChainId,
865
884
  from,
866
885
  to,
867
886
  data,
868
887
  value: valueInWei,
869
888
  nonce,
870
- gas,
871
- maxFeePerGas: fee.maxFeePerGas,
872
- maxPriorityFeePerGas: fee.maxPriorityFeePerGas,
873
- type: 'eip1559',
874
889
  };
890
+ // Add gas properties if they exist
891
+ const unsignedTx = { ...baseTx };
892
+ if (gas?.gasLimit !== undefined) {
893
+ unsignedTx.gas = gas.gasLimit;
894
+ }
895
+ if (gas?.gasPrice !== undefined) {
896
+ unsignedTx.gasPrice = gas.gasPrice;
897
+ }
898
+ if (gas?.maxFeePerGas !== undefined) {
899
+ unsignedTx.maxFeePerGas = gas.maxFeePerGas;
900
+ }
901
+ if (gas?.maxPriorityFeePerGas !== undefined) {
902
+ unsignedTx.maxPriorityFeePerGas = gas.maxPriorityFeePerGas;
903
+ }
875
904
  // Serialize transaction
876
905
  const serializedTx = serializeTransaction(unsignedTx);
877
906
  // Sign transaction via Turnkey API
@@ -941,6 +970,87 @@ export function useWaitForTxnReceipt(provider) {
941
970
  }, [provider]);
942
971
  return { waitForTxnReceipt };
943
972
  }
973
+ /**
974
+ * Hook to estimate gas for a transaction
975
+ * Returns gasLimit to pass as gas.gasLimit to useSignTxn / useSignAndSendTxn (use useGetGasPrice for fees; no estimation inside those hooks).
976
+ *
977
+ * @param provider - PublicClient instance (can be created using usePublicClient hook)
978
+ * @returns Object with estimateGas function
979
+ *
980
+ * @example
981
+ * ```tsx
982
+ * const { estimateGas } = useEstimateGas(publicClient);
983
+ * const result = await estimateGas({
984
+ * account: address!,
985
+ * to: rawTx.to,
986
+ * data: rawTx.data,
987
+ * value: rawTx.value,
988
+ * });
989
+ * // gas: { gasLimit: result.gasLimit }
990
+ * ```
991
+ */
992
+ export function useEstimateGas(provider) {
993
+ const estimateGas = useCallback(async ({ account, to, data = '0x', value = 0n, }) => {
994
+ if (!provider) {
995
+ throw new Error('Provider (publicClient) is required');
996
+ }
997
+ if (!account) {
998
+ throw new Error('Account (from) is required');
999
+ }
1000
+ if (!to) {
1001
+ throw new Error('To address is required');
1002
+ }
1003
+ const valueInWei = typeof value === 'bigint' ? value : (value === undefined || value === '' || value === '0x' ? 0n : BigInt(value));
1004
+ const gasLimit = await provider.estimateGas({
1005
+ account,
1006
+ to,
1007
+ data: data ?? '0x',
1008
+ value: valueInWei,
1009
+ });
1010
+ return { gasLimit };
1011
+ }, [provider]);
1012
+ return { estimateGas };
1013
+ }
1014
+ /**
1015
+ * Hook to get current gas price / EIP-1559 fees from the chain.
1016
+ * Use with useEstimateGas when you need gas limit and gas price for the gas param in useSignTxn / useSignAndSendTxn.
1017
+ *
1018
+ * @param provider - PublicClient instance (can be created using usePublicClient hook)
1019
+ * @returns Object with getGasPrice function returning maxFeePerGas, maxPriorityFeePerGas, and/or gasPrice
1020
+ *
1021
+ * @example
1022
+ * ```tsx
1023
+ * const { publicClient } = usePublicClient(...);
1024
+ * const { getGasPrice } = useGetGasPrice(publicClient);
1025
+ * const fees = await getGasPrice();
1026
+ * // EIP-1559: gas: { gasLimit, maxFeePerGas: fees.maxFeePerGas!, maxPriorityFeePerGas: fees.maxPriorityFeePerGas! }
1027
+ * // Legacy: gas: { gasLimit, gasPrice: fees.gasPrice! }
1028
+ * ```
1029
+ */
1030
+ export function useGetGasPrice(provider) {
1031
+ const getGasPrice = useCallback(async () => {
1032
+ if (!provider) {
1033
+ throw new Error('Provider (publicClient) is required');
1034
+ }
1035
+ const result = {};
1036
+ try {
1037
+ const fees = await provider.estimateFeesPerGas();
1038
+ result.maxFeePerGas = fees.maxFeePerGas;
1039
+ }
1040
+ catch {
1041
+ // EIP-1559 not supported, will try legacy below
1042
+ }
1043
+ try {
1044
+ result.gasPrice = await provider.getGasPrice();
1045
+ result.maxPriorityFeePerGas = await provider.estimateMaxPriorityFeePerGas();
1046
+ }
1047
+ catch {
1048
+ // Optional: gasPrice not available
1049
+ }
1050
+ return result;
1051
+ }, [provider]);
1052
+ return { getGasPrice };
1053
+ }
944
1054
  /**
945
1055
  * Hook to read from contract
946
1056
  * Reads contract data using publicClient.readContract
@@ -1010,7 +1120,7 @@ export function useReadContract(provider) {
1010
1120
  *
1011
1121
  * @example
1012
1122
  * ```tsx
1013
- * import { useExternalWalletClient } from 'signer-test-sdk-react';
1123
+ * import { useExternalWalletClient } from '@abstraxn/signer-react';
1014
1124
  *
1015
1125
  * function MyComponent() {
1016
1126
  * const { walletClient, isConnected } = useExternalWalletClient();
@@ -1058,7 +1168,7 @@ export function useExternalWalletClient() {
1058
1168
  *
1059
1169
  * @example
1060
1170
  * ```tsx
1061
- * import { useWriteContract } from 'signer-test-sdk-react';
1171
+ * import { useWriteContract } from '@abstraxn/signer-react';
1062
1172
  * import erc20Abi from './erc20Abi.json';
1063
1173
  *
1064
1174
  * function MyComponent() {
@@ -1100,36 +1210,55 @@ export function useWriteContract() {
1100
1210
  const { walletClient: hookClient, isPending, isError, error, isConnected } = useExternalWalletClient();
1101
1211
  const config = useConfig();
1102
1212
  const currentChainId = useWagmiChainId();
1103
- const writeContract = useCallback(({ address, abi, functionName, args, value, account, gas, gasPrice, maxFeePerGas, maxPriorityFeePerGas, nonce, }) => {
1213
+ const writeContract = useCallback(({ address, abi, functionName, args, value, account, gas, gasLimit, gasPrice, maxFeePerGas, maxPriorityFeePerGas, nonce, }) => {
1104
1214
  return (async () => {
1105
1215
  let activeClient = hookClient;
1106
1216
  // If hook client is missing or in error, try to recover
1107
1217
  if (!activeClient || isError) {
1108
- try {
1109
- // Try to get client directly
1110
- activeClient = await getWalletClient(config);
1218
+ // Check if the initial error was a chain mismatch
1219
+ const isMismatch = isError && (error?.name === 'ConnectorChainMismatchError' || error?.message?.includes('ChainMismatch'));
1220
+ if (isMismatch) {
1221
+ try {
1222
+ if (!currentChainId)
1223
+ throw new Error('Current chain ID is not available');
1224
+ await switchChain(config, { chainId: currentChainId });
1225
+ // Retry getting client after switch
1226
+ activeClient = await getWalletClient(config);
1227
+ }
1228
+ catch (switchErr) {
1229
+ console.error("Failed to auto-switch chain:", switchErr);
1230
+ // Fall through to try getWalletClient directly or throw
1231
+ }
1111
1232
  }
1112
- catch (err) {
1113
- // If mismatch error, try to switch chain
1114
- if (err?.name === 'ConnectorChainMismatchError' || err?.message?.includes('ChainMismatch')) {
1115
- try {
1116
- if (!currentChainId)
1117
- throw new Error('Current chain ID is not available');
1118
- await switchChain(config, { chainId: currentChainId });
1119
- // Retry getting client
1120
- activeClient = await getWalletClient(config);
1121
- }
1122
- catch (switchErr) {
1123
- throw new Error(`Failed to switch chain: ${switchErr instanceof Error ? switchErr.message : 'Unknown error'}`);
1124
- }
1233
+ // If we still don't have a client (or switch failed), try to get it directly
1234
+ if (!activeClient) {
1235
+ try {
1236
+ // Try to get client directly
1237
+ activeClient = await getWalletClient(config);
1125
1238
  }
1126
- else {
1127
- // Re-throw if it's not a mismatch we can handle
1128
- if (isError && error) {
1129
- console.error("WalletClient Initialization Error:", error);
1130
- throw new Error(`Failed to initialize WalletClient: ${error.message}. Please try reconnecting your wallet.`);
1239
+ catch (err) {
1240
+ // If mismatch error (and we haven't tried switching yet or it failed differently), try to switch chain
1241
+ // This catches cases where getWalletClient throws mismatch but the hook error wasn't mismatch (unlikely but possible)
1242
+ if (err?.name === 'ConnectorChainMismatchError' || err?.message?.includes('ChainMismatch')) {
1243
+ try {
1244
+ if (!currentChainId)
1245
+ throw new Error('Current chain ID is not available');
1246
+ await switchChain(config, { chainId: currentChainId });
1247
+ // Retry getting client
1248
+ activeClient = await getWalletClient(config);
1249
+ }
1250
+ catch (switchErr) {
1251
+ throw new Error(`Failed to switch chain: ${switchErr instanceof Error ? switchErr.message : 'Unknown error'}`);
1252
+ }
1253
+ }
1254
+ else {
1255
+ // Re-throw if it's not a mismatch we can handle
1256
+ if (isError && error) {
1257
+ console.error("WalletClient Initialization Error:", error);
1258
+ throw new Error(`Failed to initialize WalletClient: ${error.message}. Please try reconnecting your wallet.`);
1259
+ }
1260
+ throw err;
1131
1261
  }
1132
- throw err;
1133
1262
  }
1134
1263
  }
1135
1264
  }
@@ -1169,7 +1298,7 @@ export function useWriteContract() {
1169
1298
  'Make sure the function exists in the ABI and is a state-changing function.');
1170
1299
  }
1171
1300
  // Prepare the call options (viem contract write methods accept options as the last parameter)
1172
- const hasOptions = value !== undefined || account !== undefined || gas !== undefined ||
1301
+ const hasOptions = value !== undefined || account !== undefined || gas !== undefined || gasLimit !== undefined ||
1173
1302
  gasPrice !== undefined || maxFeePerGas !== undefined ||
1174
1303
  maxPriorityFeePerGas !== undefined || nonce !== undefined;
1175
1304
  // Viem contract write methods expect args as an array, not spread
@@ -1180,8 +1309,13 @@ export function useWriteContract() {
1180
1309
  callOptions.value = value;
1181
1310
  if (account !== undefined)
1182
1311
  callOptions.account = account;
1183
- if (gas !== undefined)
1312
+ // `gas` in viem is the gas *limit*. Allow either `gas` or `gasLimit` from the hook caller.
1313
+ if (gas !== undefined) {
1184
1314
  callOptions.gas = gas;
1315
+ }
1316
+ else if (gasLimit !== undefined) {
1317
+ callOptions.gas = gasLimit;
1318
+ }
1185
1319
  if (gasPrice !== undefined)
1186
1320
  callOptions.gasPrice = gasPrice;
1187
1321
  if (maxFeePerGas !== undefined)
@@ -1210,7 +1344,7 @@ export function useWriteContract() {
1210
1344
  *
1211
1345
  * @example
1212
1346
  * ```tsx
1213
- * import { useConnectionType } from 'signer-test-sdk-react';
1347
+ * import { useConnectionType } from '@abstraxn/signer-react';
1214
1348
  *
1215
1349
  * function MyComponent() {
1216
1350
  * const { connectionType, connectorMeta } = useConnectionType();
@@ -1262,4 +1396,112 @@ function normalizeConnectionType(type) {
1262
1396
  // Return original if no match (for other wallet types like coinbase, phantom, etc.)
1263
1397
  return type;
1264
1398
  }
1399
+ /**
1400
+ * Hook to switch chain
1401
+ * Handles both internal (social) and external wallets
1402
+ */
1403
+ export function useSwitchChain() {
1404
+ const { wallet, connectionType } = useAbstraxnWallet();
1405
+ const { switchChainAsync } = useWagmiSwitchChain();
1406
+ const { isConnected: isWagmiConnected } = useAccount();
1407
+ const config = useConfig();
1408
+ const switchChain = async (chainId) => {
1409
+ // Normalize connection type
1410
+ const type = connectionType ? connectionType.toLowerCase() : '';
1411
+ // Check if it's a social login
1412
+ const isSocial = ['google', 'email', 'otp', 'x', 'discord', 'passkey'].some(t => type.includes(t));
1413
+ if (isSocial) {
1414
+ if (!wallet)
1415
+ throw new Error('Wallet not initialized');
1416
+ // Use internal wallet switch
1417
+ await wallet.switchChain(chainId);
1418
+ }
1419
+ else if (isWagmiConnected) {
1420
+ // Use wagmi for external wallets
1421
+ try {
1422
+ await switchChainAsync({ chainId });
1423
+ }
1424
+ catch (error) {
1425
+ // Check if error is related to chain not being added or RPC URL missing
1426
+ // "UserRejectedRequestError" with "chain.rpcUrls is undefined" often means the chain isn't known to the wallet/viem
1427
+ // Try to add the chain if we have its details
1428
+ let chainParams = null;
1429
+ // 1. Try to get from internal SDK chains
1430
+ const chainData = getChainById(chainId);
1431
+ if (chainData && chainData.type === 'evm') {
1432
+ chainParams = {
1433
+ chainName: chainData.displayName,
1434
+ nativeCurrency: chainData.nativeCurrency,
1435
+ rpcUrls: [chainData.rpcUrl],
1436
+ blockExplorerUrls: chainData.blockExplorer ? [chainData.blockExplorer.url] : undefined,
1437
+ };
1438
+ }
1439
+ // 2. If not found, try to get from wagmi config (includes custom chains passed to provider)
1440
+ if (!chainParams) {
1441
+ const wagmiChain = config.chains.find(c => c.id === chainId);
1442
+ if (wagmiChain) {
1443
+ // Handle both viem Chain (rpcUrls) and CoreChain (rpcUrl) formats
1444
+ // The chain object in config might be a CoreChain if it wasn't converted correctly
1445
+ const rpcUrls = wagmiChain.rpcUrls?.default?.http || (wagmiChain.rpcUrl ? [wagmiChain.rpcUrl] : []);
1446
+ const blockExplorerUrls = wagmiChain.blockExplorers?.default?.url
1447
+ ? [wagmiChain.blockExplorers.default.url]
1448
+ : (wagmiChain.explorerUrl ? [wagmiChain.explorerUrl] : undefined);
1449
+ chainParams = {
1450
+ chainName: wagmiChain.name,
1451
+ nativeCurrency: wagmiChain.nativeCurrency,
1452
+ rpcUrls: rpcUrls,
1453
+ blockExplorerUrls: blockExplorerUrls,
1454
+ };
1455
+ }
1456
+ }
1457
+ if (chainParams) {
1458
+ try {
1459
+ await switchChainAsync({
1460
+ chainId,
1461
+ addEthereumChainParameter: chainParams
1462
+ });
1463
+ }
1464
+ catch (retryError) {
1465
+ console.error('Failed to add and switch chain:', retryError);
1466
+ throw retryError;
1467
+ }
1468
+ }
1469
+ else {
1470
+ // If we don't have chain data, rethrow the original error
1471
+ throw error;
1472
+ }
1473
+ }
1474
+ }
1475
+ else {
1476
+ throw new Error('No active connection to switch chain');
1477
+ }
1478
+ };
1479
+ return { switchChain };
1480
+ }
1481
+ /**
1482
+ * Hook to sign a message
1483
+ * Handles both internal (social) and external wallets
1484
+ */
1485
+ export function useSignMessage() {
1486
+ const { wallet, connectionType } = useAbstraxnWallet();
1487
+ const { signMessageAsync } = useWagmiSignMessage();
1488
+ const { isConnected: isWagmiConnected } = useAccount();
1489
+ const signMessage = async (message) => {
1490
+ // Normalize connection type
1491
+ const type = connectionType ? connectionType.toLowerCase() : '';
1492
+ // Check if it's a social login
1493
+ const isSocial = ['google', 'email', 'otp', 'x', 'discord', 'passkey'].some(t => type.includes(t));
1494
+ if (isSocial) {
1495
+ throw new Error('Signing messages is not supported for embedded wallets');
1496
+ }
1497
+ else if (isWagmiConnected) {
1498
+ // Use wagmi for external wallets
1499
+ return await signMessageAsync({ message });
1500
+ }
1501
+ else {
1502
+ throw new Error('No active connection to sign message');
1503
+ }
1504
+ };
1505
+ return { signMessage };
1506
+ }
1265
1507
  //# sourceMappingURL=hooks.js.map