@naculus/connect-appkit-react 0.1.9 → 0.2.0

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 (94) hide show
  1. package/README.md +4 -4
  2. package/dist/client.cjs +1 -1
  3. package/dist/client.cjs.map +1 -1
  4. package/dist/client.d.cts +144 -0
  5. package/dist/client.d.ts +144 -0
  6. package/dist/client.js +1 -1
  7. package/dist/client.js.map +1 -1
  8. package/dist/index.cjs +2 -1
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.d.cts +2270 -0
  11. package/dist/index.d.ts +2270 -0
  12. package/dist/index.js +2 -1
  13. package/dist/index.js.map +1 -1
  14. package/package.json +30 -12
  15. package/api-extractor.json +0 -21
  16. package/src/chain-abstraction/index.ts +0 -8
  17. package/src/chain-abstraction/useCompareCosts.ts +0 -137
  18. package/src/chain-abstraction/useExecuteRoute.ts +0 -129
  19. package/src/chain-abstraction/useRouteQuote.ts +0 -168
  20. package/src/client.test.ts +0 -242
  21. package/src/client.ts +0 -265
  22. package/src/hooks/useAccount.test.ts +0 -67
  23. package/src/hooks/useAccount.ts +0 -37
  24. package/src/hooks/useBalance.test.ts +0 -459
  25. package/src/hooks/useBalance.ts +0 -170
  26. package/src/hooks/useChain.test.ts +0 -160
  27. package/src/hooks/useChain.ts +0 -53
  28. package/src/hooks/useConnect.test.ts +0 -112
  29. package/src/hooks/useConnect.ts +0 -29
  30. package/src/hooks/useDisconnect.test.ts +0 -75
  31. package/src/hooks/useDisconnect.ts +0 -32
  32. package/src/hooks/useERC20Allowance.ts +0 -93
  33. package/src/hooks/useERC20Approve.ts +0 -220
  34. package/src/hooks/useERC20Transfer.ts +0 -134
  35. package/src/hooks/useERC20TransferSimulation.ts +0 -147
  36. package/src/hooks/useEmbeddedWallet.test.ts +0 -266
  37. package/src/hooks/useEmbeddedWallet.ts +0 -181
  38. package/src/hooks/useLastTx.test.ts +0 -117
  39. package/src/hooks/useLastTx.ts +0 -73
  40. package/src/hooks/useLookupAddress.ts +0 -131
  41. package/src/hooks/useNotification.ts +0 -308
  42. package/src/hooks/useResolveName.ts +0 -128
  43. package/src/hooks/useSIWxLogin.test.ts +0 -307
  44. package/src/hooks/useSIWxLogin.ts +0 -163
  45. package/src/hooks/useSIWxSession.test.ts +0 -481
  46. package/src/hooks/useSIWxSession.ts +0 -290
  47. package/src/hooks/useSendCalls.ts +0 -103
  48. package/src/hooks/useSendTransaction.test.ts +0 -175
  49. package/src/hooks/useSendTransaction.ts +0 -80
  50. package/src/hooks/useSendUserOperation.ts +0 -313
  51. package/src/hooks/useSession.ts +0 -96
  52. package/src/hooks/useSessionKeys.ts +0 -356
  53. package/src/hooks/useSignInWithEthereum.test.ts +0 -224
  54. package/src/hooks/useSignInWithEthereum.ts +0 -46
  55. package/src/hooks/useSignInWithX.test.ts +0 -210
  56. package/src/hooks/useSignInWithX.ts +0 -141
  57. package/src/hooks/useSignMessage.test.ts +0 -151
  58. package/src/hooks/useSignMessage.ts +0 -65
  59. package/src/hooks/useSimulateTransfer.ts +0 -165
  60. package/src/hooks/useSiwxAuthSession.test.ts +0 -456
  61. package/src/hooks/useSiwxAuthSession.ts +0 -163
  62. package/src/hooks/useSmartAccount.ts +0 -194
  63. package/src/hooks/useSwitchChain.ts +0 -68
  64. package/src/hooks/useTokenBalance.test.ts +0 -337
  65. package/src/hooks/useTokenBalance.ts +0 -210
  66. package/src/hooks/useTransactionSimulation.ts +0 -401
  67. package/src/hooks/useTxHistory.test.ts +0 -108
  68. package/src/hooks/useTxHistory.ts +0 -83
  69. package/src/hooks/useTxMonitor.test.ts +0 -127
  70. package/src/hooks/useTxMonitor.ts +0 -178
  71. package/src/hooks/useUserOpStatus.ts +0 -245
  72. package/src/hooks/useValidateDestination.test.ts +0 -96
  73. package/src/hooks/useValidateDestination.ts +0 -72
  74. package/src/hooks/useViemClient.test.ts +0 -155
  75. package/src/hooks/useViemClient.ts +0 -65
  76. package/src/hooks/useWallet.test.ts +0 -133
  77. package/src/hooks/useWallet.ts +0 -39
  78. package/src/hooks/useWeb3ErrorHandler.ts +0 -102
  79. package/src/index.ts +0 -186
  80. package/src/provider/Web3ConnectProvider.test.tsx +0 -178
  81. package/src/provider/Web3ConnectProvider.tsx +0 -530
  82. package/src/token-list/TokenSelector.tsx +0 -351
  83. package/src/token-list/defaults.ts +0 -39
  84. package/src/token-list/index.ts +0 -14
  85. package/src/token-list/useTokenList.ts +0 -119
  86. package/src/token-list/useTokenSearch.ts +0 -99
  87. package/src/types/index.ts +0 -99
  88. package/src/utils/chains.ts +0 -115
  89. package/src/utils/errorMessages.ts +0 -142
  90. package/src/utils/i18n.ts +0 -90
  91. package/src/wc-generated/components.ts +0 -377
  92. package/test/setup.ts +0 -17
  93. package/test/test-utils.tsx +0 -78
  94. package/tsup.config.ts +0 -18
@@ -1,356 +0,0 @@
1
- "use client";
2
-
3
- import { useState, useCallback, useEffect, useRef } from "react";
4
- import { useWeb3 } from "../provider/Web3ConnectProvider";
5
- import { getClient } from "../client";
6
- import { WalletError, SessionKeyManager, MemoryStorageAdapter } from "@naculus/connect-core";
7
- import type {
8
- SessionKeyScope,
9
- SessionKeyInfo,
10
- SessionKeyManagerConfig,
11
- } from "@naculus/connect-core";
12
-
13
- // ─── Internal singleton for session key management ─────────────────────
14
- // In a full production setup, this would be injected via context or client config.
15
-
16
- let globalSessionKeyManager: SessionKeyManager | null = null;
17
-
18
- function getSessionKeyManager(config?: SessionKeyManagerConfig): SessionKeyManager {
19
- if (!globalSessionKeyManager) {
20
- globalSessionKeyManager = new SessionKeyManager(
21
- config,
22
- // Use MemoryStorageAdapter for SSR safety; browser integration will use LocalStorageAdapter
23
- typeof window !== "undefined" ? undefined : new MemoryStorageAdapter(),
24
- );
25
- }
26
- return globalSessionKeyManager;
27
- }
28
-
29
- // ─── useSessionKeys ────────────────────────────────────────────────────
30
-
31
- export interface UseSessionKeysReturn {
32
- /** All session keys (active, revoked, expired) */
33
- sessions: SessionKeyInfo[];
34
- /** Only active session keys */
35
- activeSessions: SessionKeyInfo[];
36
- /** Whether data is loading */
37
- loading: boolean;
38
- /** Error from last operation */
39
- error: Error | null;
40
- /** Refresh the session list from storage */
41
- refresh: () => Promise<void>;
42
- /** Clear any error */
43
- clearError: () => void;
44
- /** Whether the storage backend is available */
45
- storageAvailable: boolean;
46
- }
47
-
48
- /**
49
- * Hook to list and manage session keys.
50
- *
51
- * @example
52
- * ```tsx
53
- * const { sessions, activeSessions, refresh } = useSessionKeys();
54
- * ```
55
- */
56
- export function useSessionKeys(): UseSessionKeysReturn {
57
- const { session } = useWeb3();
58
- const [sessions, setSessions] = useState<SessionKeyInfo[]>([]);
59
- const [loading, setLoading] = useState(false);
60
- const [error, setError] = useState<Error | null>(null);
61
- const mountedRef = useRef(true);
62
-
63
- const clearError = useCallback(() => setError(null), []);
64
-
65
- const manager = getSessionKeyManager();
66
- const storageAvailable = manager.isStorageAvailable();
67
-
68
- const refresh = useCallback(async () => {
69
- if (!session) {
70
- setSessions([]);
71
- return;
72
- }
73
-
74
- setLoading(true);
75
- setError(null);
76
- try {
77
- const keys = await manager.listSessions();
78
- if (mountedRef.current) {
79
- setSessions(keys);
80
- }
81
- } catch (err) {
82
- if (mountedRef.current) {
83
- setError(err instanceof Error ? err : new Error("Failed to load session keys"));
84
- }
85
- } finally {
86
- if (mountedRef.current) {
87
- setLoading(false);
88
- }
89
- }
90
- }, [session, manager]);
91
-
92
- // Load sessions on mount and on session change
93
- useEffect(() => {
94
- mountedRef.current = true;
95
- refresh();
96
- return () => {
97
- mountedRef.current = false;
98
- };
99
- }, [refresh]);
100
-
101
- const activeSessions = sessions.filter((s) => s.status === "active");
102
-
103
- return {
104
- sessions,
105
- activeSessions,
106
- loading,
107
- error,
108
- refresh,
109
- clearError,
110
- storageAvailable,
111
- };
112
- }
113
-
114
- // ─── useCreateSessionKey ───────────────────────────────────────────────
115
-
116
- export interface UseCreateSessionKeyReturn {
117
- /** Create a new session key */
118
- createSessionKey: (
119
- scope?: Partial<SessionKeyScope>,
120
- signerAddress?: `0x${string}`,
121
- ) => Promise<SessionKeyInfo>;
122
- /** The last created session key info */
123
- lastCreated: SessionKeyInfo | null;
124
- /** Whether creation is in progress */
125
- isCreating: boolean;
126
- /** Error from last creation */
127
- error: Error | null;
128
- /** Clear error */
129
- clearError: () => void;
130
- }
131
-
132
- /**
133
- * Hook to create new session keys.
134
- *
135
- * @example
136
- * ```tsx
137
- * const { createSessionKey, lastCreated, isCreating } = useCreateSessionKey();
138
- *
139
- * const handleCreate = async () => {
140
- * const session = await createSessionKey({
141
- * expiry: Math.floor(Date.now() / 1000) + 1800, // 30 min
142
- * maxTotalValue: parseEther("0.1"),
143
- * });
144
- * };
145
- * ```
146
- */
147
- export function useCreateSessionKey(): UseCreateSessionKeyReturn {
148
- const { session } = useWeb3();
149
- const [lastCreated, setLastCreated] = useState<SessionKeyInfo | null>(null);
150
- const [isCreating, setIsCreating] = useState(false);
151
- const [error, setError] = useState<Error | null>(null);
152
-
153
- const clearError = useCallback(() => setError(null), []);
154
-
155
- const manager = getSessionKeyManager();
156
-
157
- const createSessionKey = useCallback(
158
- async (
159
- scope?: Partial<SessionKeyScope>,
160
- signerAddress?: `0x${string}`,
161
- ): Promise<SessionKeyInfo> => {
162
- if (!session) {
163
- throw new WalletError("wallet_unavailable", "No active wallet session");
164
- }
165
-
166
- setIsCreating(true);
167
- setError(null);
168
- try {
169
- const resolvedSigner = signerAddress ?? undefined;
170
- const info = await manager.createSessionKey(scope, resolvedSigner);
171
- setLastCreated(info);
172
- return info;
173
- } catch (err) {
174
- const errorObj = err instanceof Error ? err : new Error("Failed to create session key");
175
- setError(errorObj);
176
- throw errorObj;
177
- } finally {
178
- setIsCreating(false);
179
- }
180
- },
181
- [session, manager],
182
- );
183
-
184
- return {
185
- createSessionKey,
186
- lastCreated,
187
- isCreating,
188
- error,
189
- clearError,
190
- };
191
- }
192
-
193
- // ─── useRevokeSession ──────────────────────────────────────────────────
194
-
195
- export interface UseRevokeSessionReturn {
196
- /** Revoke a session key by ID */
197
- revokeSession: (sessionId: string) => Promise<void>;
198
- /** Whether revoking is in progress */
199
- isRevoking: boolean;
200
- /** Error from last operation */
201
- error: Error | null;
202
- /** Clear error */
203
- clearError: () => void;
204
- }
205
-
206
- /**
207
- * Hook to revoke a session key.
208
- *
209
- * @example
210
- * ```tsx
211
- * const { revokeSession, isRevoking } = useRevokeSession();
212
- * await revokeSession(sessionId);
213
- * ```
214
- */
215
- export function useRevokeSession(): UseRevokeSessionReturn {
216
- const [isRevoking, setIsRevoking] = useState(false);
217
- const [error, setError] = useState<Error | null>(null);
218
-
219
- const clearError = useCallback(() => setError(null), []);
220
-
221
- const manager = getSessionKeyManager();
222
-
223
- const revokeSession = useCallback(
224
- async (sessionId: string): Promise<void> => {
225
- setIsRevoking(true);
226
- setError(null);
227
- try {
228
- await manager.revokeSession(sessionId);
229
- } catch (err) {
230
- const errorObj = err instanceof Error ? err : new Error("Failed to revoke session key");
231
- setError(errorObj);
232
- throw errorObj;
233
- } finally {
234
- setIsRevoking(false);
235
- }
236
- },
237
- [manager],
238
- );
239
-
240
- return {
241
- revokeSession,
242
- isRevoking,
243
- error,
244
- clearError,
245
- };
246
- }
247
-
248
- // ─── useSendWithSession ────────────────────────────────────────────────
249
-
250
- export interface UseSendWithSessionReturn {
251
- /** Sign a message hash using a session key */
252
- signWithSession: (sessionId: string, messageHash: `0x${string}`) => Promise<`0x${string}`>;
253
- /** Check if a transaction is within a session's scope */
254
- checkScope: (
255
- sessionId: string,
256
- tx: {
257
- to?: string;
258
- value?: string;
259
- data?: string;
260
- chainId?: number;
261
- gas?: string;
262
- },
263
- ) => Promise<{
264
- valid: boolean;
265
- reason?: string;
266
- remainingGas?: bigint;
267
- remainingValue?: bigint;
268
- remainingTxCount?: number;
269
- }>;
270
- /** Whether an operation is in progress */
271
- isBusy: boolean;
272
- /** Error from last operation */
273
- error: Error | null;
274
- /** Clear error */
275
- clearError: () => void;
276
- }
277
-
278
- /**
279
- * Hook to sign transactions using session keys and check scope.
280
- *
281
- * @example
282
- * ```tsx
283
- * const { signWithSession, checkScope } = useSendWithSession();
284
- *
285
- * const check = await checkScope(sessionId, tx);
286
- * if (check.valid) {
287
- * const sig = await signWithSession(sessionId, messageHash);
288
- * }
289
- * ```
290
- */
291
- export function useSendWithSession(): UseSendWithSessionReturn {
292
- const [isBusy, setIsBusy] = useState(false);
293
- const [error, setError] = useState<Error | null>(null);
294
-
295
- const clearError = useCallback(() => setError(null), []);
296
-
297
- const manager = getSessionKeyManager();
298
-
299
- const signWithSession = useCallback(
300
- async (sessionId: string, messageHash: `0x${string}`): Promise<`0x${string}`> => {
301
- setIsBusy(true);
302
- setError(null);
303
- try {
304
- return await manager.signWithSessionKey(sessionId, messageHash);
305
- } catch (err) {
306
- const errorObj = err instanceof Error ? err : new Error("Failed to sign with session key");
307
- setError(errorObj);
308
- throw errorObj;
309
- } finally {
310
- setIsBusy(false);
311
- }
312
- },
313
- [manager],
314
- );
315
-
316
- const checkScope = useCallback(
317
- async (
318
- sessionId: string,
319
- tx: {
320
- to?: string;
321
- value?: string;
322
- data?: string;
323
- chainId?: number;
324
- gas?: string;
325
- },
326
- ) => {
327
- setIsBusy(true);
328
- setError(null);
329
- try {
330
- return await manager.checkSessionScope(sessionId, tx);
331
- } catch (err) {
332
- const errorObj = err instanceof Error ? err : new Error("Failed to check session scope");
333
- setError(errorObj);
334
- throw errorObj;
335
- } finally {
336
- setIsBusy(false);
337
- }
338
- },
339
- [manager],
340
- );
341
-
342
- return {
343
- signWithSession,
344
- checkScope,
345
- isBusy,
346
- error,
347
- clearError,
348
- };
349
- }
350
-
351
- /**
352
- * Reset the global session key manager (useful for testing / cleanup).
353
- */
354
- export function resetSessionKeyManager(): void {
355
- globalSessionKeyManager = null;
356
- }
@@ -1,224 +0,0 @@
1
- /// <reference types="vitest" />
2
- /// @vitest-environment jsdom
3
-
4
- import { describe, it, expect, vi, beforeEach } from "vitest";
5
- import { renderHook, act } from "@testing-library/react";
6
-
7
- const mockUseWeb3 = vi.fn();
8
- vi.mock("../provider/Web3ConnectProvider", () => ({
9
- useWeb3: () => mockUseWeb3(),
10
- Web3ConnectProvider: ({ children }: { children: React.ReactNode }) => children,
11
- }));
12
-
13
- const mockSignMessage = vi.fn();
14
- const mockGetClient = vi.fn();
15
- vi.mock("../client", () => ({
16
- getClient: () => mockGetClient(),
17
- }));
18
-
19
- import { useSignInWithEthereum } from "./useSignInWithEthereum";
20
-
21
- function createEvmSession() {
22
- return {
23
- topic: "test-topic",
24
- namespaces: {
25
- eip155: {
26
- chains: ["eip155:1"],
27
- accounts: ["eip155:1:0x1234567890123456789012345678901234567890"],
28
- },
29
- },
30
- };
31
- }
32
-
33
- describe("useSignInWithEthereum", () => {
34
- beforeEach(() => {
35
- vi.clearAllMocks();
36
- });
37
-
38
- it("should have initial idle state", () => {
39
- mockUseWeb3.mockReturnValue({ session: null, chainId: null });
40
- mockGetClient.mockReturnValue(null);
41
-
42
- const { result } = renderHook(() => useSignInWithEthereum());
43
-
44
- expect(result.current.isSigningIn).toBe(false);
45
- expect(result.current.result).toBeNull();
46
- expect(result.current.error).toBeNull();
47
- });
48
-
49
- it("should throw when no session", async () => {
50
- mockUseWeb3.mockReturnValue({ session: null, chainId: null });
51
- mockGetClient.mockReturnValue({
52
- signMessage: mockSignMessage,
53
- });
54
-
55
- const { result } = renderHook(() => useSignInWithEthereum());
56
-
57
- await expect(result.current.signIn()).rejects.toThrow("No active session");
58
- });
59
-
60
- it("should throw when client not initialized", async () => {
61
- mockUseWeb3.mockReturnValue({ session: createEvmSession(), chainId: "eip155:1" });
62
- mockGetClient.mockReturnValue(null);
63
-
64
- const { result } = renderHook(() => useSignInWithEthereum());
65
-
66
- await expect(result.current.signIn()).rejects.toThrow("Client not initialized");
67
- });
68
-
69
- it("should throw when no EVM accounts in session", async () => {
70
- const solanaSession = {
71
- topic: "test-topic",
72
- namespaces: {
73
- solana: {
74
- chains: ["solana:4sGjMW1s"],
75
- accounts: ["solana:4sGjMW1s:5JG7DPRQAxJVCLx3GxsHTxP1KZbSyLmPQBLkLhFZPGrH"],
76
- },
77
- },
78
- };
79
-
80
- mockUseWeb3.mockReturnValue({ session: solanaSession, chainId: null });
81
- mockGetClient.mockReturnValue({
82
- signMessage: mockSignMessage,
83
- });
84
-
85
- const { result } = renderHook(() => useSignInWithEthereum());
86
-
87
- await expect(result.current.signIn()).rejects.toThrow(
88
- "No EVM (eip155) accounts found in session"
89
- );
90
- });
91
-
92
- it("should sign in with Ethereum successfully", async () => {
93
- const mockSignature = "0xsiwsignature1234567890abcdef";
94
- mockSignMessage.mockResolvedValue(mockSignature);
95
- mockUseWeb3.mockReturnValue({
96
- session: createEvmSession(),
97
- chainId: "eip155:1",
98
- });
99
- mockGetClient.mockReturnValue({
100
- signMessage: mockSignMessage,
101
- });
102
-
103
- const { result } = renderHook(() => useSignInWithEthereum());
104
-
105
- let siwxResult: Awaited<ReturnType<typeof result.current.signIn>> | undefined;
106
-
107
- await act(async () => {
108
- siwxResult = await result.current.signIn({
109
- statement: "Sign in to MyApp",
110
- });
111
- });
112
-
113
- expect(siwxResult!).toBeDefined();
114
- expect(siwxResult!.signature).toBe(mockSignature);
115
- expect(siwxResult!.message.domain).toBe("localhost:3000");
116
- expect(siwxResult!.message.address).toBe("eip155:1:0x1234567890123456789012345678901234567890");
117
- expect(siwxResult!.message.statement).toBe("Sign in to MyApp");
118
- expect(siwxResult!.message.version).toBe(1);
119
- expect(siwxResult!.message.chainId).toBe("eip155:1");
120
- expect(siwxResult!.message.nonce).toHaveLength(16);
121
- expect(siwxResult!.message.issuedAt).toBeTruthy();
122
- expect(mockSignMessage).toHaveBeenCalledTimes(1);
123
- expect(result.current.isSigningIn).toBe(false);
124
- expect(result.current.result).toBe(siwxResult);
125
- });
126
-
127
- it("should set loading state during signing", async () => {
128
- let resolvePromise: (v: string) => void;
129
- const signPromise = new Promise<string>((resolve) => {
130
- resolvePromise = resolve;
131
- });
132
- mockSignMessage.mockReturnValue(signPromise);
133
- mockUseWeb3.mockReturnValue({
134
- session: createEvmSession(),
135
- chainId: "eip155:1",
136
- });
137
- mockGetClient.mockReturnValue({
138
- signMessage: mockSignMessage,
139
- });
140
-
141
- const { result } = renderHook(() => useSignInWithEthereum());
142
-
143
- let callPromise: Promise<unknown>;
144
- act(() => {
145
- callPromise = result.current.signIn();
146
- });
147
-
148
- expect(result.current.isSigningIn).toBe(true);
149
-
150
- await act(async () => {
151
- resolvePromise!("0xsig");
152
- await callPromise!;
153
- });
154
-
155
- expect(result.current.isSigningIn).toBe(false);
156
- });
157
-
158
- it("should capture error on failed signing", async () => {
159
- mockSignMessage.mockRejectedValue(new Error("User rejected"));
160
- mockUseWeb3.mockReturnValue({
161
- session: createEvmSession(),
162
- chainId: "eip155:1",
163
- });
164
- mockGetClient.mockReturnValue({
165
- signMessage: mockSignMessage,
166
- });
167
-
168
- const { result } = renderHook(() => useSignInWithEthereum());
169
-
170
- await act(async () => {
171
- try {
172
- await result.current.signIn();
173
- } catch {
174
- // Expected
175
- }
176
- });
177
-
178
- expect(result.current.error).not.toBeNull();
179
- expect(result.current.error?.message).toBe("User rejected");
180
- });
181
-
182
- it("should clear error", () => {
183
- mockUseWeb3.mockReturnValue({ session: null, chainId: null });
184
- mockGetClient.mockReturnValue(null);
185
-
186
- const { result } = renderHook(() => useSignInWithEthereum());
187
-
188
- act(() => {
189
- result.current.clearError();
190
- });
191
-
192
- expect(result.current.error).toBeNull();
193
- });
194
-
195
- it("should accept custom domain and URI", async () => {
196
- const mockSignature = "0xsig";
197
- mockSignMessage.mockResolvedValue(mockSignature);
198
- mockUseWeb3.mockReturnValue({
199
- session: createEvmSession(),
200
- chainId: "eip155:1",
201
- });
202
- mockGetClient.mockReturnValue({
203
- signMessage: mockSignMessage,
204
- });
205
-
206
- const { result } = renderHook(() => useSignInWithEthereum());
207
-
208
- let siwxResult: Awaited<ReturnType<typeof result.current.signIn>> | undefined;
209
-
210
- await act(async () => {
211
- siwxResult = await result.current.signIn({
212
- domain: "app.example.com",
213
- uri: "https://app.example.com/login",
214
- expirySeconds: 3600,
215
- resources: ["https://app.example.com/privacy"],
216
- });
217
- });
218
-
219
- expect(siwxResult!.message.domain).toBe("app.example.com");
220
- expect(siwxResult!.message.uri).toBe("https://app.example.com/login");
221
- expect(siwxResult!.message.expirationTime).toBeTruthy();
222
- expect(siwxResult!.message.resources).toContain("https://app.example.com/privacy");
223
- });
224
- });
@@ -1,46 +0,0 @@
1
- import { useSignInWithX } from "./useSignInWithX";
2
- import type { UseSignInWithXOptions, UseSignInWithXReturn } from "./useSignInWithX";
3
- import { WalletError } from "@naculus/connect-core";
4
- import { useWeb3 } from "../provider/Web3ConnectProvider";
5
- import { useCallback } from "react";
6
-
7
- export interface UseSignInWithEthereumOptions extends UseSignInWithXOptions {}
8
-
9
- export interface UseSignInWithEthereumReturn extends UseSignInWithXReturn {}
10
-
11
- function useEip155SessionGuard(): () => void {
12
- const { session } = useWeb3();
13
- return useCallback(() => {
14
- if (!session) {
15
- throw new WalletError("wallet_unavailable", "No active session");
16
- }
17
- const evmNamespace = session.namespaces["eip155"];
18
- if (!evmNamespace || evmNamespace.accounts.length === 0) {
19
- throw new WalletError(
20
- "namespace_mismatch",
21
- "No EVM (eip155) accounts found in session"
22
- );
23
- }
24
- }, [session]);
25
- }
26
-
27
- export function useSignInWithEthereum(): UseSignInWithEthereumReturn {
28
- const guard = useEip155SessionGuard();
29
- const siwx = useSignInWithX();
30
-
31
- const signIn = useCallback(
32
- async (options?: UseSignInWithEthereumOptions) => {
33
- guard();
34
- return siwx.signIn(options);
35
- },
36
- [guard, siwx.signIn]
37
- );
38
-
39
- return {
40
- signIn,
41
- isSigningIn: siwx.isSigningIn,
42
- result: siwx.result,
43
- error: siwx.error,
44
- clearError: siwx.clearError,
45
- };
46
- }