@0xkey-io/react-native-wallet-kit 0.1.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 (61) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +93 -0
  3. package/dist/hooks/use-0xkey.d.ts +3 -0
  4. package/dist/hooks/use-0xkey.d.ts.map +1 -0
  5. package/dist/hooks/use-0xkey.js +15 -0
  6. package/dist/hooks/use-0xkey.js.map +1 -0
  7. package/dist/hooks/use-0xkey.mjs +13 -0
  8. package/dist/hooks/use-0xkey.mjs.map +1 -0
  9. package/dist/index.d.ts +21 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +55 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/index.mjs +6 -0
  14. package/dist/index.mjs.map +1 -0
  15. package/dist/providers/Types.d.ts +275 -0
  16. package/dist/providers/Types.d.ts.map +1 -0
  17. package/dist/providers/Types.js +9 -0
  18. package/dist/providers/Types.js.map +1 -0
  19. package/dist/providers/Types.mjs +7 -0
  20. package/dist/providers/Types.mjs.map +1 -0
  21. package/dist/providers/ZeroXKeyProvider.d.ts +39 -0
  22. package/dist/providers/ZeroXKeyProvider.d.ts.map +1 -0
  23. package/dist/providers/ZeroXKeyProvider.js +1846 -0
  24. package/dist/providers/ZeroXKeyProvider.js.map +1 -0
  25. package/dist/providers/ZeroXKeyProvider.mjs +1844 -0
  26. package/dist/providers/ZeroXKeyProvider.mjs.map +1 -0
  27. package/dist/providers/index.d.ts +4 -0
  28. package/dist/providers/index.d.ts.map +1 -0
  29. package/dist/tests/oauth-test.d.ts +2 -0
  30. package/dist/tests/oauth-test.d.ts.map +1 -0
  31. package/dist/typedoc-entry/index.d.ts +5 -0
  32. package/dist/typedoc-entry/index.d.ts.map +1 -0
  33. package/dist/types/base.d.ts +137 -0
  34. package/dist/types/base.d.ts.map +1 -0
  35. package/dist/types/base.js +48 -0
  36. package/dist/types/base.js.map +1 -0
  37. package/dist/types/base.mjs +48 -0
  38. package/dist/types/base.mjs.map +1 -0
  39. package/dist/types/method-types.d.ts +102 -0
  40. package/dist/types/method-types.d.ts.map +1 -0
  41. package/dist/utils/index.d.ts +4 -0
  42. package/dist/utils/index.d.ts.map +1 -0
  43. package/dist/utils/oauth.d.ts +240 -0
  44. package/dist/utils/oauth.d.ts.map +1 -0
  45. package/dist/utils/oauth.js +340 -0
  46. package/dist/utils/oauth.js.map +1 -0
  47. package/dist/utils/oauth.mjs +319 -0
  48. package/dist/utils/oauth.mjs.map +1 -0
  49. package/dist/utils/timers.d.ts +73 -0
  50. package/dist/utils/timers.d.ts.map +1 -0
  51. package/dist/utils/timers.js +132 -0
  52. package/dist/utils/timers.js.map +1 -0
  53. package/dist/utils/timers.mjs +122 -0
  54. package/dist/utils/timers.mjs.map +1 -0
  55. package/dist/utils/utils.d.ts +27 -0
  56. package/dist/utils/utils.d.ts.map +1 -0
  57. package/dist/utils/utils.js +37 -0
  58. package/dist/utils/utils.js.map +1 -0
  59. package/dist/utils/utils.mjs +33 -0
  60. package/dist/utils/utils.mjs.map +1 -0
  61. package/package.json +80 -0
@@ -0,0 +1,1846 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var utils = require('../utils/utils.js');
5
+ var timers = require('../utils/timers.js');
6
+ var oauth = require('../utils/oauth.js');
7
+ var core = require('@0xkey-io/core');
8
+ var react = require('react');
9
+ var reactNative = require('react-native');
10
+ var DeviceInfo = require('react-native-device-info');
11
+ var reactNativeInappbrowserReborn = require('react-native-inappbrowser-reborn');
12
+ var sha2 = require('@noble/hashes/sha2');
13
+ var utils$1 = require('@noble/hashes/utils');
14
+ var sdkTypes = require('@0xkey-io/sdk-types');
15
+ var base = require('../types/base.js');
16
+ var Types = require('./Types.js');
17
+ var crypto = require('@0xkey-io/crypto');
18
+
19
+ /**
20
+ * Provides ZeroXKey client authentication, session management, wallet operations, and user profile management
21
+ * for the React Native Wallet Kit SDK. This context provider encapsulates all core authentication flows (Passkey, OTP, OAuth),
22
+ * session lifecycle (creation, expiration, refresh), wallet import/export, and user profile updates (email, phone, name).
23
+ *
24
+ * The provider automatically initializes the ZeroXKey client, fetches configuration (including proxy auth config if needed),
25
+ * and synchronizes session and authentication state. It exposes a comprehensive set of methods for authentication flows,
26
+ * wallet management, and user profile operations, as well as UI handlers for modal-driven flows.
27
+ *
28
+ * Features:
29
+ * - Passkey, OTP (Email/SMS), and OAuth (Google, Apple, Facebook, Discord, X) authentication and sign-up flows.
30
+ * - React Native-specific OAuth: opens an in-app browser (Custom Tabs/Safari View Controller) and deep-links back via the configured app scheme.
31
+ * - Session management: creation, expiration scheduling, refresh, and clearing.
32
+ * - Wallet management: fetch, import, export, account management.
33
+ * - User profile management: email, phone, name, OAuth provider, and passkey linking/removal.
34
+ * - Error handling and callback integration for custom error and event responses.
35
+ *
36
+ * Usage:
37
+ * Wrap your application with `ZeroXKeyProvider` to enable authentication and wallet features via context.
38
+ *
39
+ * @param config - The ZeroXKey provider configuration object.
40
+ * @param children - React children to be rendered within the provider.
41
+ * @param callbacks - Optional callbacks for error handling and session events.
42
+ *
43
+ * @returns A React context provider exposing authentication, wallet, and user management methods and state.
44
+ */
45
+ const ZeroXKeyProvider = ({ config, children, callbacks, }) => {
46
+ const [client, setClient] = react.useState(undefined);
47
+ const [session, setSession] = react.useState(undefined);
48
+ const [masterConfig, setMasterConfig] = react.useState(undefined);
49
+ const [wallets, setWallets] = react.useState([]);
50
+ const [user, setUser] = react.useState(undefined);
51
+ const [clientState, setClientState] = react.useState();
52
+ const [authState, setAuthState] = react.useState(base.AuthState.Unauthenticated);
53
+ const expiryTimeoutsRef = react.useRef({});
54
+ const proxyAuthConfigRef = react.useRef(null);
55
+ const [allSessions, setAllSessions] = react.useState(undefined);
56
+ // if there is no authProxyConfigId or if autoFetchWalletKitConfig is specifically
57
+ // set to false, we don't need to fetch the config
58
+ const shouldFetchWalletKitConfig = config.authProxyConfigId != null &&
59
+ config.authProxyConfigId !== "" &&
60
+ config.autoFetchWalletKitConfig !== false;
61
+ const buildConfig = (proxyAuthConfig) => {
62
+ // Juggle the local overrides with the values set in the dashboard (proxyAuthConfig).
63
+ // Normalize potentially empty string values coming from the app-level config
64
+ const sanitizedAuthProxyUrl = config.authProxyUrl && config.authProxyUrl.trim()
65
+ ? config.authProxyUrl
66
+ : undefined;
67
+ // Resolve OTP enablement
68
+ const emailOtpEnabled = config.auth?.otp?.email ??
69
+ proxyAuthConfig?.enabledProviders.includes("email") ??
70
+ false;
71
+ const smsOtpEnabled = config.auth?.otp?.sms ??
72
+ proxyAuthConfig?.enabledProviders.includes("sms") ??
73
+ false;
74
+ // Resolve shared redirect; do NOT attach scheme here. We'll attach in handler on demand.
75
+ const appScheme = config.auth?.oauth?.appScheme ?? undefined;
76
+ const redirectUrl = config.auth?.oauth?.redirectUri ??
77
+ proxyAuthConfig?.oauthRedirectUrl ??
78
+ oauth.ZEROXKEY_OAUTH_REDIRECT_URL;
79
+ // Warn if they are trying to set auth proxy only settings directly
80
+ if (proxyAuthConfig) {
81
+ if (config.auth?.sessionExpirationSeconds) {
82
+ console.warn("ZeroXKey SDK warning. You have set sessionExpirationSeconds directly in the ZeroXKeyProvider. This setting will be ignored because you are using an auth proxy. Please configure session expiration in the ZeroXKey dashboard.");
83
+ }
84
+ if (config.auth?.otp?.alphanumeric !== undefined &&
85
+ shouldFetchWalletKitConfig) {
86
+ console.warn("ZeroXKey SDK warning. You have set otpAlphanumeric directly in the ZeroXKeyProvider. This setting will be ignored because you are using an auth proxy. Please configure OTP settings in the ZeroXKey dashboard.");
87
+ }
88
+ if (config.auth?.otp?.length && shouldFetchWalletKitConfig) {
89
+ console.warn("ZeroXKey SDK warning. You have set otpLength directly in the ZeroXKeyProvider. This setting will be ignored because you are using an auth proxy. Please configure OTP settings in the ZeroXKey dashboard.");
90
+ }
91
+ }
92
+ // These are settings that can only be set via the auth proxy config
93
+ const authProxyPrioSettings = {
94
+ sessionExpirationSeconds: proxyAuthConfig?.sessionExpirationSeconds ??
95
+ config.auth?.sessionExpirationSeconds,
96
+ otp: {
97
+ alphanumeric: proxyAuthConfig?.otpAlphanumeric ??
98
+ config.auth?.otp?.alphanumeric ??
99
+ true,
100
+ length: proxyAuthConfig?.otpLength ?? config.auth?.otp?.length ?? "6",
101
+ },
102
+ };
103
+ return {
104
+ ...config,
105
+ // Ensure empty strings are not forwarded as URLs
106
+ authProxyUrl: sanitizedAuthProxyUrl,
107
+ // Overrides:
108
+ auth: {
109
+ ...config.auth,
110
+ // Proxy-controlled settings
111
+ sessionExpirationSeconds: authProxyPrioSettings.sessionExpirationSeconds,
112
+ otp: {
113
+ ...config.auth?.otp,
114
+ // Enablement flags
115
+ email: emailOtpEnabled,
116
+ sms: smsOtpEnabled,
117
+ // Proxy-only settings
118
+ alphanumeric: authProxyPrioSettings.otp.alphanumeric,
119
+ length: authProxyPrioSettings.otp.length,
120
+ },
121
+ // OAuth shared settings
122
+ oauth: {
123
+ ...config.auth?.oauth,
124
+ ...(appScheme && { appScheme }),
125
+ redirectUri: redirectUrl,
126
+ },
127
+ autoRefreshSession: config.auth?.autoRefreshSession ?? true,
128
+ },
129
+ autoRefreshManagedState: config.autoRefreshManagedState ?? true,
130
+ };
131
+ };
132
+ const getOauthProviderSettings = (provider) => {
133
+ const oauth$1 = masterConfig?.auth?.oauth;
134
+ const providerConfig = oauth$1 ? oauth$1[provider] : undefined;
135
+ const providerObjectConfig = providerConfig && typeof providerConfig === "object"
136
+ ? providerConfig
137
+ : undefined;
138
+ const proxyClientIds = proxyAuthConfigRef.current?.oauthClientIds;
139
+ const clientId = providerObjectConfig?.clientId ??
140
+ (proxyClientIds ? proxyClientIds[provider] : undefined);
141
+ const appScheme = oauth$1?.appScheme;
142
+ // For Discord and X, default to scheme-based deep link if not explicitly provided.
143
+ const redirectUri = providerObjectConfig?.redirectUri ??
144
+ ((provider === "discord" || provider === "x") && appScheme
145
+ ? `${appScheme}://`
146
+ : (oauth$1?.redirectUri ??
147
+ proxyAuthConfigRef.current?.oauthRedirectUrl ??
148
+ oauth.ZEROXKEY_OAUTH_REDIRECT_URL));
149
+ return { clientId, redirectUri, appScheme };
150
+ };
151
+ /**
152
+ * Initializes the ZeroXKey client with the provided configuration.
153
+ * This function sets up the client, fetches the proxy auth config if needed,
154
+ * and prepares the client for use in authentication and wallet operations.
155
+ *
156
+ * @internal
157
+ */
158
+ const initializeClient = async () => {
159
+ if (!masterConfig || client || clientState == base.ClientState.Loading)
160
+ return;
161
+ try {
162
+ setClientState(base.ClientState.Loading);
163
+ const zeroXKeyClient = new core.ZeroXKeyClient({
164
+ apiBaseUrl: masterConfig.apiBaseUrl,
165
+ authProxyUrl: masterConfig.authProxyUrl,
166
+ authProxyConfigId: masterConfig.authProxyConfigId,
167
+ organizationId: masterConfig.organizationId,
168
+ defaultStamperType: masterConfig.defaultStamperType,
169
+ // Define passkey and wallet config here. If we don't pass it into the client, Mr. Client will assume that we don't want to use passkeys/wallets and not create the stamper!
170
+ passkeyConfig: {
171
+ rpId: masterConfig.passkeyConfig?.rpId,
172
+ timeout: masterConfig.passkeyConfig?.timeout || 60000, // 60 seconds
173
+ userVerification: masterConfig.passkeyConfig?.userVerification || "preferred",
174
+ allowCredentials: masterConfig.passkeyConfig?.allowCredentials || [],
175
+ },
176
+ });
177
+ await zeroXKeyClient.init();
178
+ setClient(zeroXKeyClient);
179
+ // Don't set clientState to ready until we fetch the proxy auth config (See other fetchProxyAuthConfig useEffect)
180
+ }
181
+ catch (error) {
182
+ setClientState(base.ClientState.Error);
183
+ if (error instanceof sdkTypes.ZeroXKeyError ||
184
+ error instanceof sdkTypes.ZeroXKeyNetworkError) {
185
+ callbacks?.onError?.(error);
186
+ }
187
+ else {
188
+ callbacks?.onError?.(new sdkTypes.ZeroXKeyError(`Failed to initialize ZeroXKey client`, sdkTypes.ZeroXKeyErrorCodes.INITIALIZE_CLIENT_ERROR, error));
189
+ }
190
+ }
191
+ };
192
+ /**
193
+ * @internal
194
+ * Schedules a session expiration and warning timer for the given session key.
195
+ *
196
+ * - Sets up two timers: one for warning before expiry and one for actual expiry.
197
+ * - Uses capped timeouts under the hood so delays > 24.8 days are safe (see utils/timers.ts).
198
+ *
199
+ * @param params.sessionKey - The key of the session to schedule expiration for.
200
+ * @param params.expiry - The expiration time in seconds since epoch.
201
+ * @throws {ZeroXKeyError} If an error occurs while scheduling the session expiration.
202
+ */
203
+ async function scheduleSessionExpiration(params) {
204
+ const { sessionKey, expiry } = params;
205
+ try {
206
+ const warnKey = `${sessionKey}-warning`;
207
+ // Replace any prior timers for this session
208
+ timers.clearKey(expiryTimeoutsRef.current, sessionKey);
209
+ timers.clearKey(expiryTimeoutsRef.current, warnKey);
210
+ const now = Date.now();
211
+ const expiryMs = expiry * 1000;
212
+ const timeUntilExpiry = expiryMs - now;
213
+ const beforeExpiry = async () => {
214
+ const activeSession = await getSession();
215
+ if (!activeSession && expiryTimeoutsRef.current[warnKey]) {
216
+ // Keep nudging until session materializes (short 10s timer is fine)
217
+ timers.setTimeoutInMap(expiryTimeoutsRef.current, warnKey, beforeExpiry, 10_000);
218
+ return;
219
+ }
220
+ const session = await getSession({ sessionKey });
221
+ if (!session)
222
+ return;
223
+ callbacks?.beforeSessionExpiry?.({ sessionKey });
224
+ if (masterConfig?.auth?.autoRefreshSession) {
225
+ await refreshSession({
226
+ expirationSeconds: session.expirationSeconds,
227
+ sessionKey,
228
+ });
229
+ }
230
+ };
231
+ const expireSession = async () => {
232
+ const expiredSession = await getSession({ sessionKey });
233
+ if (!expiredSession)
234
+ return;
235
+ callbacks?.onSessionExpired?.({ sessionKey });
236
+ if ((await getActiveSessionKey()) === sessionKey) {
237
+ setSession(undefined);
238
+ }
239
+ setAllSessions((prev) => {
240
+ if (!prev)
241
+ return prev;
242
+ const next = { ...prev };
243
+ delete next[sessionKey];
244
+ return next;
245
+ });
246
+ await clearSession({ sessionKey });
247
+ // Remove timers for this session
248
+ timers.clearKey(expiryTimeoutsRef.current, sessionKey);
249
+ timers.clearKey(expiryTimeoutsRef.current, warnKey);
250
+ await logout();
251
+ };
252
+ // Already expired → expire immediately
253
+ if (timeUntilExpiry <= 0) {
254
+ await expireSession();
255
+ return;
256
+ }
257
+ // Warning timer (if threshold is in the future)
258
+ const warnAt = expiryMs - utils.SESSION_WARNING_THRESHOLD_MS;
259
+ if (warnAt <= now) {
260
+ void beforeExpiry(); // fire-and-forget is fine
261
+ }
262
+ else {
263
+ timers.setCappedTimeoutInMap(expiryTimeoutsRef.current, warnKey, beforeExpiry, warnAt - now);
264
+ }
265
+ // Actual expiry timer (safe for long delays)
266
+ timers.setCappedTimeoutInMap(expiryTimeoutsRef.current, sessionKey, expireSession, timeUntilExpiry);
267
+ }
268
+ catch (error) {
269
+ if (error instanceof sdkTypes.ZeroXKeyError ||
270
+ error instanceof sdkTypes.ZeroXKeyNetworkError) {
271
+ callbacks?.onError?.(error);
272
+ }
273
+ else {
274
+ callbacks?.onError?.(new sdkTypes.ZeroXKeyError(`Failed to schedule session expiration for ${sessionKey}`, sdkTypes.ZeroXKeyErrorCodes.SCHEDULE_SESSION_EXPIRY_ERROR, error));
275
+ }
276
+ }
277
+ }
278
+ /**
279
+ * Clears all scheduled session timers (warning + expiry).
280
+ *
281
+ * - Removes all active timers managed by this client.
282
+ * - Useful on re-init or logout to avoid stale timers.
283
+ *
284
+ * @throws {ZeroXKeyError} If an error occurs while clearing the timers.
285
+ */
286
+ function clearSessionTimeouts(sessionKeys) {
287
+ try {
288
+ if (sessionKeys) {
289
+ timers.clearKeys(expiryTimeoutsRef.current, sessionKeys);
290
+ }
291
+ else {
292
+ timers.clearAll(expiryTimeoutsRef.current); // clears & deletes everything
293
+ }
294
+ }
295
+ catch (error) {
296
+ if (error instanceof sdkTypes.ZeroXKeyError ||
297
+ error instanceof sdkTypes.ZeroXKeyNetworkError) {
298
+ callbacks?.onError?.(error);
299
+ }
300
+ else {
301
+ callbacks?.onError?.(new sdkTypes.ZeroXKeyError("Failed to clear session timeouts", sdkTypes.ZeroXKeyErrorCodes.CLEAR_SESSION_TIMEOUTS_ERROR, error));
302
+ }
303
+ }
304
+ }
305
+ /**
306
+ * Initializes the user sessions by fetching all active sessions and setting up their state.
307
+ * @internal
308
+ */
309
+ const initializeSessions = async () => {
310
+ setSession(undefined);
311
+ setAllSessions(undefined);
312
+ try {
313
+ const allLocalStorageSessions = await getAllSessions();
314
+ if (!allLocalStorageSessions)
315
+ return;
316
+ await Promise.all(Object.keys(allLocalStorageSessions).map(async (sessionKey) => {
317
+ const s = allLocalStorageSessions?.[sessionKey];
318
+ if (!utils.isValidSession(s)) {
319
+ await clearSession({ sessionKey });
320
+ if (sessionKey === (await getActiveSessionKey())) {
321
+ setSession(undefined);
322
+ }
323
+ delete allLocalStorageSessions[sessionKey];
324
+ return;
325
+ }
326
+ await scheduleSessionExpiration({
327
+ sessionKey,
328
+ expiry: s.expiry,
329
+ });
330
+ }));
331
+ setAllSessions(allLocalStorageSessions || undefined);
332
+ const activeSessionKey = await client?.getActiveSessionKey();
333
+ if (activeSessionKey) {
334
+ if (!allLocalStorageSessions[activeSessionKey]) {
335
+ return;
336
+ }
337
+ setSession(allLocalStorageSessions[activeSessionKey]);
338
+ await maybeRefreshUser();
339
+ await maybeRefreshWallets();
340
+ return;
341
+ }
342
+ }
343
+ catch (error) {
344
+ if (error instanceof sdkTypes.ZeroXKeyError ||
345
+ error instanceof sdkTypes.ZeroXKeyNetworkError) {
346
+ callbacks?.onError?.(error);
347
+ }
348
+ else {
349
+ callbacks?.onError?.(new sdkTypes.ZeroXKeyError(`Failed to initialize sessions`, sdkTypes.ZeroXKeyErrorCodes.INITIALIZE_SESSION_ERROR, error));
350
+ }
351
+ }
352
+ };
353
+ /**
354
+ * @internal
355
+ * Handles the post-authentication flow.
356
+ *
357
+ * - This function is called after a successful authentication (login or sign-up) via any supported method (Passkey, Wallet, OTP, OAuth).
358
+ * - It fetches the active session and all sessions, updates the session state, and schedules session expiration and warning timeouts.
359
+ * - It also refreshes the user's wallets and profile information to ensure the provider state is up to date.
360
+ * - This function is used internally after all authentication flows to synchronize state and trigger any necessary callbacks.
361
+ *
362
+ * @returns A void promise.
363
+ * @throws {ZeroXKeyError} If the client is not initialized or if there is an error during the process.
364
+ */
365
+ const handlePostAuth = async (params) => {
366
+ const { method, action, identifier } = params;
367
+ try {
368
+ const sessionKey = await getActiveSessionKey();
369
+ const session = await getSession({
370
+ ...(sessionKey && { sessionKey }),
371
+ });
372
+ if (session && sessionKey)
373
+ await scheduleSessionExpiration({
374
+ sessionKey,
375
+ expiry: session.expiry,
376
+ });
377
+ const allSessions = await client.getAllSessions();
378
+ setSession(session);
379
+ setAllSessions(allSessions);
380
+ await maybeRefreshWallets();
381
+ await maybeRefreshUser();
382
+ callbacks?.onAuthenticationSuccess?.({
383
+ session,
384
+ method,
385
+ action,
386
+ identifier,
387
+ });
388
+ }
389
+ catch (error) {
390
+ if (error instanceof sdkTypes.ZeroXKeyError ||
391
+ error instanceof sdkTypes.ZeroXKeyNetworkError) {
392
+ callbacks?.onError?.(error);
393
+ }
394
+ else {
395
+ callbacks?.onError?.(new sdkTypes.ZeroXKeyError(`Failed to handle post-authentication`, sdkTypes.ZeroXKeyErrorCodes.HANDLE_POST_AUTH_ERROR, error));
396
+ }
397
+ }
398
+ };
399
+ /**
400
+ * @internal
401
+ * Handles the post-logout flow.
402
+ *
403
+ * - This function is called after a successful logout or session clear.
404
+ * - It clears all scheduled session expiration and warning timeouts associated to the session key to prevent memory leaks.
405
+ * - It resets the session state, removes user data from memory, the logged out session from all sessions state, and clears the wallets list.
406
+ * - This ensures that all sensitive information is removed from the provider state after logout.
407
+ * - Called internally after logout or when all sessions are cleared.
408
+ *
409
+ * @returns void
410
+ * @throws {ZeroXKeyError} If there is an error during the post-logout process.
411
+ */
412
+ const handlePostLogout = (sessionKey) => {
413
+ try {
414
+ clearSessionTimeouts(sessionKey ? [sessionKey, `${sessionKey}-warning`] : undefined);
415
+ setAllSessions((prev) => {
416
+ if (!prev)
417
+ return prev;
418
+ if (sessionKey) {
419
+ const next = { ...prev };
420
+ delete next[sessionKey];
421
+ return next;
422
+ }
423
+ return {};
424
+ });
425
+ setSession(undefined);
426
+ setUser(undefined);
427
+ setWallets([]);
428
+ }
429
+ catch (error) {
430
+ callbacks?.onError?.(new sdkTypes.ZeroXKeyError(`Failed to initialize sessions`, sdkTypes.ZeroXKeyErrorCodes.HANDLE_POST_LOGOUT_ERROR, error));
431
+ }
432
+ };
433
+ const createPasskey = react.useCallback(async (params) => {
434
+ if (!client) {
435
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
436
+ }
437
+ return utils.withZeroXKeyErrorHandling(() => client.createPasskey({ ...params }), () => logout(), callbacks, "Failed to create passkey");
438
+ }, [client, callbacks]);
439
+ const createHttpClient = react.useCallback((params) => {
440
+ if (!client) {
441
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
442
+ }
443
+ return client.createHttpClient(params);
444
+ }, [client]);
445
+ const logout = react.useCallback(async (params) => {
446
+ if (!client) {
447
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
448
+ }
449
+ await utils.withZeroXKeyErrorHandling(async () => {
450
+ // If no sessionKey is provided, we try to get the active one.
451
+ let sessionKey = params?.sessionKey;
452
+ if (!sessionKey)
453
+ sessionKey = await getActiveSessionKey();
454
+ await client.logout(params);
455
+ // We only handle post logout if the sessionKey is defined since that means we actually logged out of a session.
456
+ if (sessionKey)
457
+ handlePostLogout(sessionKey);
458
+ }, () => logout(), callbacks, "Failed to logout");
459
+ return;
460
+ }, [client, callbacks]);
461
+ const loginWithPasskey = react.useCallback(async (params) => {
462
+ if (!client) {
463
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
464
+ }
465
+ const expirationSeconds = params?.expirationSeconds ??
466
+ masterConfig?.auth?.sessionExpirationSeconds ??
467
+ core.DEFAULT_SESSION_EXPIRATION_IN_SECONDS;
468
+ const res = await utils.withZeroXKeyErrorHandling(() => client.loginWithPasskey({ ...params, expirationSeconds }), () => logout(), callbacks, "Failed to login with passkey");
469
+ if (res) {
470
+ await handlePostAuth({
471
+ method: base.AuthMethod.Passkey,
472
+ action: sdkTypes.AuthAction.LOGIN,
473
+ identifier: res.credentialId,
474
+ });
475
+ }
476
+ return res;
477
+ }, [client, callbacks]);
478
+ const signUpWithPasskey = react.useCallback(async (params) => {
479
+ if (!client) {
480
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
481
+ }
482
+ if (!masterConfig) {
483
+ throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
484
+ }
485
+ // If createSubOrgParams is not provided, use the default from masterConfig
486
+ let createSubOrgParams = params?.createSubOrgParams ??
487
+ masterConfig.auth?.createSuborgParams?.passkeyAuth;
488
+ params =
489
+ createSubOrgParams !== undefined
490
+ ? { ...params, createSubOrgParams }
491
+ : { ...params };
492
+ const expirationSeconds = params.expirationSeconds ??
493
+ masterConfig?.auth?.sessionExpirationSeconds ??
494
+ core.DEFAULT_SESSION_EXPIRATION_IN_SECONDS;
495
+ const websiteName = reactNative.Platform.OS === "web" && typeof window !== "undefined"
496
+ ? window.location.hostname
497
+ : DeviceInfo.getApplicationName() ||
498
+ DeviceInfo.getBundleId() ||
499
+ "mobile-app";
500
+ const timestamp = new Date().toLocaleDateString() +
501
+ "-" +
502
+ new Date().toLocaleTimeString([], {
503
+ hour: "2-digit",
504
+ minute: "2-digit",
505
+ });
506
+ // We allow passkeyName to be passed in thru the provider or thru the params of this function directly.
507
+ // This is because signUpWithPasskey will create a new passkey using that name.
508
+ // Any extra authenticators will be created after the first one. (see core implementation)
509
+ const passkeyName = params?.passkeyDisplayName ??
510
+ masterConfig.auth?.createSuborgParams?.passkeyAuth?.passkeyName ??
511
+ `${websiteName}-${timestamp}`;
512
+ const res = await utils.withZeroXKeyErrorHandling(() => client.signUpWithPasskey({
513
+ ...params,
514
+ passkeyDisplayName: passkeyName,
515
+ expirationSeconds,
516
+ }), () => logout(), callbacks, "Failed to sign up with passkey");
517
+ if (res) {
518
+ await handlePostAuth({
519
+ method: base.AuthMethod.Passkey,
520
+ action: sdkTypes.AuthAction.SIGNUP,
521
+ identifier: res.credentialId,
522
+ });
523
+ }
524
+ return res;
525
+ }, [client, callbacks]);
526
+ const initOtp = react.useCallback(async (params) => {
527
+ if (!client) {
528
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
529
+ }
530
+ return utils.withZeroXKeyErrorHandling(() => client.initOtp(params), () => logout(), callbacks, "Failed to initialize OTP");
531
+ }, [client, callbacks]);
532
+ const verifyOtp = react.useCallback(async (params) => {
533
+ if (!client) {
534
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
535
+ }
536
+ return utils.withZeroXKeyErrorHandling(() => client.verifyOtp(params), () => logout(), callbacks, "Failed to verify OTP");
537
+ }, [client, callbacks]);
538
+ const loginWithOtp = react.useCallback(async (params) => {
539
+ if (!client) {
540
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
541
+ }
542
+ const res = await utils.withZeroXKeyErrorHandling(() => client.loginWithOtp(params), () => logout(), callbacks, "Failed to login with OTP");
543
+ if (res) {
544
+ await handlePostAuth({
545
+ method: base.AuthMethod.Otp,
546
+ action: sdkTypes.AuthAction.LOGIN,
547
+ identifier: params.verificationToken,
548
+ });
549
+ }
550
+ return res;
551
+ }, [client, callbacks]);
552
+ const signUpWithOtp = react.useCallback(async (params) => {
553
+ if (!client) {
554
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
555
+ }
556
+ if (!masterConfig) {
557
+ throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
558
+ }
559
+ // If createSubOrgParams is not provided, use the default from masterConfig
560
+ let createSubOrgParams = params.createSubOrgParams;
561
+ if (!createSubOrgParams && masterConfig?.auth?.createSuborgParams) {
562
+ if (params.otpType === core.OtpType.Email) {
563
+ createSubOrgParams =
564
+ masterConfig.auth.createSuborgParams.emailOtpAuth;
565
+ }
566
+ else if (params.otpType === core.OtpType.Sms) {
567
+ createSubOrgParams = masterConfig.auth.createSuborgParams.smsOtpAuth;
568
+ }
569
+ }
570
+ params =
571
+ createSubOrgParams !== undefined
572
+ ? { ...params, createSubOrgParams }
573
+ : { ...params };
574
+ const res = await utils.withZeroXKeyErrorHandling(() => client.signUpWithOtp(params), () => logout(), callbacks, "Failed to sign up with OTP");
575
+ if (res) {
576
+ await handlePostAuth({
577
+ method: base.AuthMethod.Otp,
578
+ action: sdkTypes.AuthAction.SIGNUP,
579
+ identifier: params.verificationToken,
580
+ });
581
+ }
582
+ return res;
583
+ }, [client, callbacks, masterConfig]);
584
+ const completeOtp = react.useCallback(async (params) => {
585
+ if (!client) {
586
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
587
+ }
588
+ if (!masterConfig) {
589
+ throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
590
+ }
591
+ // If createSubOrgParams is not provided, use the default from masterConfig
592
+ let createSubOrgParams = params.createSubOrgParams;
593
+ if (!createSubOrgParams && masterConfig?.auth?.createSuborgParams) {
594
+ if (params.otpType === core.OtpType.Email) {
595
+ createSubOrgParams =
596
+ masterConfig.auth.createSuborgParams.emailOtpAuth;
597
+ }
598
+ else if (params.otpType === core.OtpType.Sms) {
599
+ createSubOrgParams = masterConfig.auth.createSuborgParams.smsOtpAuth;
600
+ }
601
+ }
602
+ params =
603
+ createSubOrgParams !== undefined
604
+ ? { ...params, createSubOrgParams }
605
+ : { ...params };
606
+ const res = await utils.withZeroXKeyErrorHandling(() => client.completeOtp(params), () => logout(), callbacks, "Failed to complete OTP");
607
+ if (res) {
608
+ await handlePostAuth({
609
+ method: base.AuthMethod.Otp,
610
+ action: res.action,
611
+ identifier: res.verificationToken,
612
+ });
613
+ }
614
+ return res;
615
+ }, [client, callbacks, masterConfig]);
616
+ const loginWithOauth = react.useCallback(async (params) => {
617
+ if (!client) {
618
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
619
+ }
620
+ const res = await utils.withZeroXKeyErrorHandling(() => client.loginWithOauth(params), () => logout(), callbacks, "Failed to login with OAuth");
621
+ if (res) {
622
+ await handlePostAuth({
623
+ method: base.AuthMethod.Oauth,
624
+ action: sdkTypes.AuthAction.LOGIN,
625
+ identifier: params.oidcToken,
626
+ });
627
+ }
628
+ return res;
629
+ }, [client, callbacks]);
630
+ const signUpWithOauth = react.useCallback(async (params) => {
631
+ if (!client) {
632
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
633
+ }
634
+ if (!masterConfig) {
635
+ throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
636
+ }
637
+ // If createSubOrgParams is not provided, use the default from masterConfig
638
+ let createSubOrgParams = params.createSubOrgParams ??
639
+ masterConfig.auth?.createSuborgParams?.oauth;
640
+ params =
641
+ createSubOrgParams !== undefined
642
+ ? { ...params, createSubOrgParams }
643
+ : { ...params };
644
+ const res = await utils.withZeroXKeyErrorHandling(() => client.signUpWithOauth(params), () => logout(), callbacks, "Failed to sign up with OAuth");
645
+ if (res) {
646
+ await handlePostAuth({
647
+ method: base.AuthMethod.Oauth,
648
+ action: sdkTypes.AuthAction.SIGNUP,
649
+ identifier: params.oidcToken,
650
+ });
651
+ }
652
+ return res;
653
+ }, [client, callbacks, masterConfig]);
654
+ const completeOauth = react.useCallback(async (params) => {
655
+ if (!client) {
656
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
657
+ }
658
+ if (!masterConfig) {
659
+ throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
660
+ }
661
+ // If createSubOrgParams is not provided, use the default from masterConfig
662
+ const createSubOrgParams = params.createSubOrgParams ??
663
+ masterConfig.auth?.createSuborgParams?.oauth;
664
+ params =
665
+ createSubOrgParams !== undefined
666
+ ? { ...params, createSubOrgParams }
667
+ : { ...params };
668
+ const res = await utils.withZeroXKeyErrorHandling(() => client.completeOauth(params), () => logout(), callbacks, "Failed to complete OAuth");
669
+ if (res) {
670
+ await handlePostAuth({
671
+ method: base.AuthMethod.Oauth,
672
+ action: res.action,
673
+ identifier: params.oidcToken,
674
+ });
675
+ }
676
+ return res;
677
+ }, [client, callbacks, masterConfig]);
678
+ const fetchWallets = react.useCallback(async (params) => {
679
+ if (!client) {
680
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
681
+ }
682
+ return utils.withZeroXKeyErrorHandling(() => client.fetchWallets(params), () => logout(), callbacks, "Failed to fetch wallets");
683
+ }, [client, callbacks]);
684
+ const fetchWalletAccounts = react.useCallback(async (params) => {
685
+ if (!client) {
686
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
687
+ }
688
+ return utils.withZeroXKeyErrorHandling(() => client.fetchWalletAccounts(params), () => logout(), callbacks, "Failed to fetch wallet accounts");
689
+ }, [client, callbacks]);
690
+ const fetchPrivateKeys = react.useCallback(async (params) => {
691
+ if (!client) {
692
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
693
+ }
694
+ return utils.withZeroXKeyErrorHandling(() => client.fetchPrivateKeys(params), () => logout(), callbacks, "Failed to fetch private keys");
695
+ }, [client, callbacks]);
696
+ const fetchBootProofForAppProof = react.useCallback(async (params) => {
697
+ if (!client)
698
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
699
+ return utils.withZeroXKeyErrorHandling(() => client.fetchBootProofForAppProof(params), () => logout(), callbacks, "Failed to fetch or create delegated access user");
700
+ }, [client, callbacks]);
701
+ const signMessage = react.useCallback(async (params) => {
702
+ if (!client)
703
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
704
+ return utils.withZeroXKeyErrorHandling(() => client.signMessage(params), () => logout(), callbacks, "Failed to sign message");
705
+ }, [client, callbacks]);
706
+ const signTransaction = react.useCallback(async (params) => {
707
+ if (!client)
708
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
709
+ return utils.withZeroXKeyErrorHandling(() => client.signTransaction(params), () => logout(), callbacks, "Failed to sign transaction");
710
+ }, [client, callbacks]);
711
+ const solSendTransaction = react.useCallback(async (params) => {
712
+ if (!client)
713
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
714
+ return utils.withZeroXKeyErrorHandling(() => client.solSendTransaction(params), () => logout(), callbacks, "Failed to send sol transaction");
715
+ }, [client, callbacks]);
716
+ const ethSendTransaction = react.useCallback(async (params) => {
717
+ if (!client)
718
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
719
+ return utils.withZeroXKeyErrorHandling(() => client.ethSendTransaction(params), () => logout(), callbacks, "Failed to send eth transaction");
720
+ }, [client, callbacks]);
721
+ const ethSendErc20Transfer = react.useCallback(async (params) => {
722
+ if (!client)
723
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
724
+ return utils.withZeroXKeyErrorHandling(() => client.ethSendErc20Transfer(params), () => logout(), callbacks, "Failed to send ERC20 transfer");
725
+ }, [client, callbacks]);
726
+ const signAndSendTransaction = react.useCallback(async (params) => {
727
+ if (!client)
728
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
729
+ return utils.withZeroXKeyErrorHandling(() => client.signAndSendTransaction(params), () => logout(), callbacks, "Failed to sign and send raw transaction");
730
+ }, [client, callbacks, logout]);
731
+ const pollTransactionStatus = react.useCallback(async (params) => {
732
+ if (!client)
733
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
734
+ return utils.withZeroXKeyErrorHandling(() => client.pollTransactionStatus(params), () => logout(), callbacks, "Failed to poll transaction status");
735
+ }, [client, callbacks]);
736
+ const fetchUser = react.useCallback(async (params) => {
737
+ if (!client)
738
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
739
+ return utils.withZeroXKeyErrorHandling(() => client.fetchUser(params), () => logout(), callbacks, "Failed to fetch user");
740
+ }, [client, callbacks]);
741
+ const fetchOrCreateP256ApiKeyUser = react.useCallback(async (params) => {
742
+ if (!client)
743
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
744
+ return utils.withZeroXKeyErrorHandling(() => client.fetchOrCreateP256ApiKeyUser(params), () => logout(), callbacks, "Failed to fetch or create delegated access user");
745
+ }, [client, callbacks]);
746
+ const fetchOrCreatePolicies = react.useCallback(async (params) => {
747
+ if (!client)
748
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
749
+ return utils.withZeroXKeyErrorHandling(() => client.fetchOrCreatePolicies(params), () => logout(), callbacks, "Failed to fetch or create delegated access user");
750
+ }, [client, callbacks]);
751
+ const updateUserEmail = react.useCallback(async (params) => {
752
+ if (!client)
753
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
754
+ const res = await utils.withZeroXKeyErrorHandling(() => client.updateUserEmail(params), () => logout(), callbacks, "Failed to update user email");
755
+ if (res)
756
+ await maybeRefreshUser({
757
+ stampWith: params?.stampWith,
758
+ ...(params?.organizationId && {
759
+ organizationId: params.organizationId,
760
+ }),
761
+ ...(params?.userId && { userId: params.userId }),
762
+ });
763
+ return res;
764
+ }, [client, callbacks]);
765
+ const removeUserEmail = react.useCallback(async (params) => {
766
+ if (!client)
767
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
768
+ const res = await utils.withZeroXKeyErrorHandling(() => client.removeUserEmail(params), () => logout(), callbacks, "Failed to remove user email");
769
+ if (res)
770
+ await maybeRefreshUser({
771
+ stampWith: params?.stampWith,
772
+ ...(params?.organizationId && {
773
+ organizationId: params.organizationId,
774
+ }),
775
+ ...(params?.userId && { userId: params.userId }),
776
+ });
777
+ return res;
778
+ }, [client, callbacks]);
779
+ const updateUserPhoneNumber = react.useCallback(async (params) => {
780
+ if (!client)
781
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
782
+ const res = await utils.withZeroXKeyErrorHandling(() => client.updateUserPhoneNumber(params), () => logout(), callbacks, "Failed to update user phone number");
783
+ if (res)
784
+ await maybeRefreshUser({
785
+ stampWith: params?.stampWith,
786
+ ...(params?.organizationId && {
787
+ organizationId: params.organizationId,
788
+ }),
789
+ ...(params?.userId && { userId: params.userId }),
790
+ });
791
+ return res;
792
+ }, [client, callbacks]);
793
+ const removeUserPhoneNumber = react.useCallback(async (params) => {
794
+ if (!client)
795
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
796
+ const res = await utils.withZeroXKeyErrorHandling(() => client.removeUserPhoneNumber(params), () => logout(), callbacks, "Failed to remove user phone number");
797
+ if (res)
798
+ await maybeRefreshUser({
799
+ stampWith: params?.stampWith,
800
+ ...(params?.organizationId && {
801
+ organizationId: params.organizationId,
802
+ }),
803
+ ...(params?.userId && { userId: params.userId }),
804
+ });
805
+ return res;
806
+ }, [client, callbacks]);
807
+ const updateUserName = react.useCallback(async (params) => {
808
+ if (!client)
809
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
810
+ const res = await utils.withZeroXKeyErrorHandling(() => client.updateUserName(params), () => logout(), callbacks, "Failed to update user name");
811
+ if (res)
812
+ await maybeRefreshUser({
813
+ stampWith: params?.stampWith,
814
+ ...(params?.organizationId && {
815
+ organizationId: params.organizationId,
816
+ }),
817
+ ...(params?.userId && { userId: params.userId }),
818
+ });
819
+ return res;
820
+ }, [client, callbacks]);
821
+ const addOauthProvider = react.useCallback(async (params) => {
822
+ if (!client)
823
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
824
+ const res = await utils.withZeroXKeyErrorHandling(() => client.addOauthProvider(params), () => logout(), callbacks, "Failed to add OAuth provider");
825
+ if (res)
826
+ await maybeRefreshUser({
827
+ stampWith: params?.stampWith,
828
+ ...(params?.organizationId && {
829
+ organizationId: params.organizationId,
830
+ }),
831
+ ...(params?.userId && { userId: params.userId }),
832
+ });
833
+ return res;
834
+ }, [client, callbacks]);
835
+ const removeOauthProviders = react.useCallback(async (params) => {
836
+ if (!client)
837
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
838
+ const res = await utils.withZeroXKeyErrorHandling(() => client.removeOauthProviders(params), () => logout(), callbacks, "Failed to remove OAuth providers");
839
+ if (res)
840
+ await maybeRefreshUser({
841
+ stampWith: params?.stampWith,
842
+ ...(params?.organizationId && {
843
+ organizationId: params.organizationId,
844
+ }),
845
+ ...(params?.userId && { userId: params.userId }),
846
+ });
847
+ return res;
848
+ }, [client, callbacks]);
849
+ const addPasskey = react.useCallback(async (params) => {
850
+ if (!client)
851
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
852
+ const res = await utils.withZeroXKeyErrorHandling(() => client.addPasskey(params), () => logout(), callbacks, "Failed to add passkey");
853
+ if (res)
854
+ await maybeRefreshUser({
855
+ stampWith: params?.stampWith,
856
+ ...(params?.organizationId && {
857
+ organizationId: params.organizationId,
858
+ }),
859
+ ...(params?.userId && { userId: params.userId }),
860
+ });
861
+ return res;
862
+ }, [client, callbacks]);
863
+ const removePasskeys = react.useCallback(async (params) => {
864
+ if (!client)
865
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
866
+ const res = await utils.withZeroXKeyErrorHandling(() => client.removePasskeys(params), () => logout(), callbacks, "Failed to remove passkeys");
867
+ if (res)
868
+ await maybeRefreshUser({
869
+ stampWith: params?.stampWith,
870
+ ...(params?.organizationId && {
871
+ organizationId: params.organizationId,
872
+ }),
873
+ ...(params?.userId && { userId: params.userId }),
874
+ });
875
+ return res;
876
+ }, [client, callbacks]);
877
+ const createWallet = react.useCallback(async (params) => {
878
+ if (!client)
879
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
880
+ const res = await utils.withZeroXKeyErrorHandling(() => client.createWallet(params), () => logout(), callbacks, "Failed to create wallet");
881
+ const s = await getSession();
882
+ if (res && s)
883
+ await maybeRefreshWallets({
884
+ stampWith: params?.stampWith,
885
+ ...(params?.organizationId && {
886
+ organizationId: params.organizationId,
887
+ }),
888
+ });
889
+ return res;
890
+ }, [client, session, callbacks]);
891
+ const createWalletAccounts = react.useCallback(async (params) => {
892
+ if (!client)
893
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
894
+ const res = await utils.withZeroXKeyErrorHandling(() => client.createWalletAccounts(params), () => logout(), callbacks, "Failed to create wallet accounts");
895
+ const s = await getSession();
896
+ if (res && s)
897
+ await maybeRefreshWallets({
898
+ stampWith: params?.stampWith,
899
+ ...(params?.organizationId && {
900
+ organizationId: params.organizationId,
901
+ }),
902
+ });
903
+ return res;
904
+ }, [client, session, callbacks]);
905
+ const exportWallet = react.useCallback(async (params) => {
906
+ if (!client)
907
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
908
+ // Default: decrypt unless explicitly disabled
909
+ const shouldDecrypt = params?.decrypt !== false;
910
+ if (!shouldDecrypt) {
911
+ const res = await utils.withZeroXKeyErrorHandling(() => client.exportWallet({
912
+ walletId: params.walletId,
913
+ targetPublicKey: params.targetPublicKey,
914
+ ...(params.organizationId && {
915
+ organizationId: params.organizationId,
916
+ }),
917
+ ...(params.stampWith && { stampWith: params.stampWith }),
918
+ }), () => logout(), callbacks, "Failed to export wallet");
919
+ const s = await getSession();
920
+ if (res && s)
921
+ await maybeRefreshWallets({
922
+ stampWith: params?.stampWith,
923
+ ...(params?.organizationId && {
924
+ organizationId: params.organizationId,
925
+ }),
926
+ });
927
+ return res;
928
+ }
929
+ // Decrypting path: generate P-256 keypair, export, then decrypt to mnemonic
930
+ try {
931
+ const { privateKey, publicKeyUncompressed } = crypto.generateP256KeyPair();
932
+ const targetPublicKey = publicKeyUncompressed;
933
+ const exportParams = {
934
+ walletId: params.walletId,
935
+ targetPublicKey,
936
+ ...(params.organizationId && {
937
+ organizationId: params.organizationId,
938
+ }),
939
+ ...(params.stampWith && { stampWith: params.stampWith }),
940
+ };
941
+ const bundle = await utils.withZeroXKeyErrorHandling(() => client.exportWallet(exportParams), () => logout(), callbacks, "Failed to export wallet");
942
+ const session = await getSession();
943
+ const orgId = session?.organizationId;
944
+ if (!orgId) {
945
+ throw new sdkTypes.ZeroXKeyError("Missing organizationId in session for decryption", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
946
+ }
947
+ const mnemonic = await crypto.decryptExportBundle({
948
+ exportBundle: bundle,
949
+ embeddedKey: privateKey,
950
+ organizationId: orgId,
951
+ returnMnemonic: true,
952
+ keyFormat: "HEXADECIMAL",
953
+ });
954
+ return mnemonic;
955
+ }
956
+ catch (error) {
957
+ throw error;
958
+ }
959
+ }, [client, session, callbacks]);
960
+ const exportPrivateKey = react.useCallback(async (params) => {
961
+ if (!client)
962
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
963
+ const shouldDecrypt = params?.decrypt !== false;
964
+ if (!shouldDecrypt) {
965
+ const res = await utils.withZeroXKeyErrorHandling(() => client.exportPrivateKey({
966
+ privateKeyId: params.privateKeyId,
967
+ targetPublicKey: params.targetPublicKey,
968
+ ...(params.organizationId && {
969
+ organizationId: params.organizationId,
970
+ }),
971
+ ...(params.stampWith && { stampWith: params.stampWith }),
972
+ }), () => logout(), callbacks, "Failed to export private key");
973
+ return res;
974
+ }
975
+ try {
976
+ const { privateKey, publicKeyUncompressed } = crypto.generateP256KeyPair();
977
+ const targetPublicKey = publicKeyUncompressed;
978
+ const exportParams = {
979
+ privateKeyId: params.privateKeyId,
980
+ targetPublicKey,
981
+ ...(params.organizationId && {
982
+ organizationId: params.organizationId,
983
+ }),
984
+ ...(params.stampWith && { stampWith: params.stampWith }),
985
+ };
986
+ const bundle = await utils.withZeroXKeyErrorHandling(() => client.exportPrivateKey(exportParams), () => logout(), callbacks, "Failed to export private key");
987
+ const session = await getSession();
988
+ const orgId = session?.organizationId;
989
+ if (!orgId) {
990
+ throw new sdkTypes.ZeroXKeyError("Missing organizationId in session for decryption", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
991
+ }
992
+ const rawPrivateKey = await crypto.decryptExportBundle({
993
+ exportBundle: bundle,
994
+ embeddedKey: privateKey,
995
+ organizationId: orgId,
996
+ returnMnemonic: false,
997
+ keyFormat: "HEXADECIMAL",
998
+ });
999
+ return rawPrivateKey;
1000
+ }
1001
+ catch (error) {
1002
+ throw error;
1003
+ }
1004
+ }, [client, callbacks]);
1005
+ const exportWalletAccount = react.useCallback(async (params) => {
1006
+ if (!client)
1007
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1008
+ const shouldDecrypt = params?.decrypt !== false;
1009
+ if (!shouldDecrypt) {
1010
+ const res = await utils.withZeroXKeyErrorHandling(() => client.exportWalletAccount({
1011
+ address: params.address,
1012
+ targetPublicKey: params.targetPublicKey,
1013
+ ...(params.organizationId && {
1014
+ organizationId: params.organizationId,
1015
+ }),
1016
+ ...(params.stampWith && { stampWith: params.stampWith }),
1017
+ }), () => logout(), callbacks, "Failed to export wallet accounts");
1018
+ return res;
1019
+ }
1020
+ try {
1021
+ const { privateKey, publicKeyUncompressed } = crypto.generateP256KeyPair();
1022
+ const targetPublicKey = publicKeyUncompressed;
1023
+ const exportParams = {
1024
+ address: params.address,
1025
+ targetPublicKey,
1026
+ ...(params.organizationId && {
1027
+ organizationId: params.organizationId,
1028
+ }),
1029
+ ...(params.stampWith && { stampWith: params.stampWith }),
1030
+ };
1031
+ const bundle = await utils.withZeroXKeyErrorHandling(() => client.exportWalletAccount(exportParams), () => logout(), callbacks, "Failed to export wallet accounts");
1032
+ const session = await getSession();
1033
+ const orgId = session?.organizationId;
1034
+ if (!orgId) {
1035
+ throw new sdkTypes.ZeroXKeyError("Missing organizationId in session for decryption", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
1036
+ }
1037
+ const decryptedKey = await crypto.decryptExportBundle({
1038
+ exportBundle: bundle,
1039
+ embeddedKey: privateKey,
1040
+ organizationId: orgId,
1041
+ returnMnemonic: false,
1042
+ keyFormat: "HEXADECIMAL",
1043
+ });
1044
+ return decryptedKey;
1045
+ }
1046
+ catch (error) {
1047
+ throw error;
1048
+ }
1049
+ }, [client, callbacks, masterConfig, session, user]);
1050
+ const importWallet = react.useCallback(async (params) => {
1051
+ if (!client)
1052
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1053
+ const { mnemonic, walletName, accounts, organizationId, userId, stampWith, } = params;
1054
+ // Resolve org/user from params or current session
1055
+ const currentSession = await getSession();
1056
+ const effectiveOrgId = organizationId ?? currentSession?.organizationId;
1057
+ const effectiveUserId = userId ?? currentSession?.userId;
1058
+ if (!effectiveOrgId || !effectiveUserId) {
1059
+ throw new sdkTypes.ZeroXKeyError("Missing organizationId or userId for wallet import", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
1060
+ }
1061
+ // Step 1: init import to obtain importBundle
1062
+ const initRes = await utils.withZeroXKeyErrorHandling(() => client.httpClient?.initImportWallet({
1063
+ organizationId: effectiveOrgId,
1064
+ userId: effectiveUserId,
1065
+ }, stampWith), () => logout(), callbacks, "Failed to init wallet import");
1066
+ const importBundle = initRes?.importBundle;
1067
+ if (!importBundle) {
1068
+ throw new sdkTypes.ZeroXKeyError("Failed to retrieve import bundle", sdkTypes.ZeroXKeyErrorCodes.IMPORT_WALLET_ERROR);
1069
+ }
1070
+ // Step 2: encrypt mnemonic to encryptedBundle
1071
+ const encryptedBundle = await crypto.encryptWalletToBundle({
1072
+ mnemonic,
1073
+ importBundle,
1074
+ userId: effectiveUserId,
1075
+ organizationId: effectiveOrgId,
1076
+ });
1077
+ // Step 3: call importWallet with encrypted bundle
1078
+ const res = await utils.withZeroXKeyErrorHandling(() => client.importWallet({
1079
+ encryptedBundle,
1080
+ walletName,
1081
+ ...(accounts && { accounts }),
1082
+ organizationId: effectiveOrgId,
1083
+ userId: effectiveUserId,
1084
+ ...(stampWith && { stampWith }),
1085
+ }), () => logout(), callbacks, "Failed to import wallet");
1086
+ // Refresh state after import
1087
+ if (res)
1088
+ await maybeRefreshWallets({
1089
+ ...(stampWith && { stampWith }),
1090
+ organizationId: effectiveOrgId,
1091
+ userId: effectiveUserId,
1092
+ });
1093
+ return res;
1094
+ }, [client, callbacks, masterConfig, session, user]);
1095
+ const importPrivateKey = react.useCallback(async (params) => {
1096
+ if (!client)
1097
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1098
+ const { privateKey, privateKeyName, addressFormats, curve, keyFormat = "HEXADECIMAL", organizationId, userId, stampWith, } = params;
1099
+ // Resolve org/user
1100
+ const currentSession = await getSession();
1101
+ const effectiveOrgId = organizationId ?? currentSession?.organizationId;
1102
+ const effectiveUserId = userId ?? currentSession?.userId;
1103
+ if (!effectiveOrgId || !effectiveUserId) {
1104
+ throw new sdkTypes.ZeroXKeyError("Missing organizationId or userId for private key import", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
1105
+ }
1106
+ // Init import to get bundle
1107
+ const initRes = await utils.withZeroXKeyErrorHandling(() => client.httpClient?.initImportPrivateKey({
1108
+ organizationId: effectiveOrgId,
1109
+ userId: effectiveUserId,
1110
+ }, stampWith), () => logout(), callbacks, "Failed to init private key import");
1111
+ const importBundle = initRes?.importBundle;
1112
+ if (!importBundle) {
1113
+ throw new sdkTypes.ZeroXKeyError("Failed to retrieve import bundle", sdkTypes.ZeroXKeyErrorCodes.IMPORT_WALLET_ERROR);
1114
+ }
1115
+ // Encrypt provided private key to bundle
1116
+ const encryptedBundle = await crypto.encryptPrivateKeyToBundle({
1117
+ privateKey,
1118
+ keyFormat,
1119
+ importBundle,
1120
+ userId: effectiveUserId,
1121
+ organizationId: effectiveOrgId,
1122
+ });
1123
+ // Import
1124
+ const res = await utils.withZeroXKeyErrorHandling(() => client.importPrivateKey({
1125
+ encryptedBundle,
1126
+ privateKeyName,
1127
+ addressFormats,
1128
+ curve: curve ?? "CURVE_SECP256K1",
1129
+ organizationId: effectiveOrgId,
1130
+ userId: effectiveUserId,
1131
+ ...(stampWith && { stampWith }),
1132
+ }), () => logout(), callbacks, "Failed to import private key");
1133
+ return res;
1134
+ }, [client, callbacks, masterConfig, session, user]);
1135
+ const deleteSubOrganization = react.useCallback(async (params) => {
1136
+ if (!client)
1137
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1138
+ return utils.withZeroXKeyErrorHandling(() => client.deleteSubOrganization(params), () => logout(), callbacks, "Failed to delete sub-organization");
1139
+ }, [client, callbacks, masterConfig, session, user]);
1140
+ const storeSession = react.useCallback(async (params) => {
1141
+ if (!client)
1142
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1143
+ await utils.withZeroXKeyErrorHandling(() => client.storeSession(params), () => logout(), callbacks, "Failed to store session");
1144
+ const sessionKey = await getActiveSessionKey();
1145
+ const session = await getSession({
1146
+ ...(sessionKey && { sessionKey }),
1147
+ });
1148
+ if (session && sessionKey)
1149
+ await scheduleSessionExpiration({ sessionKey, expiry: session.expiry });
1150
+ const allSessions = await getAllSessions();
1151
+ setSession(session);
1152
+ setAllSessions(allSessions);
1153
+ await maybeRefreshWallets();
1154
+ await maybeRefreshUser();
1155
+ }, [client, callbacks, masterConfig, session, user]);
1156
+ const clearSession = react.useCallback(async (params) => {
1157
+ if (!client)
1158
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1159
+ await utils.withZeroXKeyErrorHandling(async () => client.clearSession(params), () => logout(), callbacks, "Failed to clear session");
1160
+ const sessionKey = params?.sessionKey ?? (await getActiveSessionKey());
1161
+ if (!sessionKey)
1162
+ return;
1163
+ if (!params?.sessionKey) {
1164
+ setSession(undefined);
1165
+ }
1166
+ clearSessionTimeouts([sessionKey]);
1167
+ // clear only the cleared session from allSessions
1168
+ const newAllSessions = { ...allSessions };
1169
+ if (newAllSessions) {
1170
+ delete newAllSessions[sessionKey];
1171
+ }
1172
+ setAllSessions(newAllSessions);
1173
+ return;
1174
+ }, [client, callbacks, session, user, masterConfig]);
1175
+ const clearAllSessions = react.useCallback(async () => {
1176
+ if (!client)
1177
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1178
+ setSession(undefined);
1179
+ setAllSessions(undefined);
1180
+ clearSessionTimeouts();
1181
+ return await utils.withZeroXKeyErrorHandling(() => client.clearAllSessions(), () => logout(), callbacks, "Failed to clear all sessions");
1182
+ }, [client, callbacks, session, user, masterConfig]);
1183
+ const refreshSession = react.useCallback(async (params) => {
1184
+ if (!client) {
1185
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1186
+ }
1187
+ const activeSessionKey = await client.getActiveSessionKey();
1188
+ if (!activeSessionKey) {
1189
+ throw new sdkTypes.ZeroXKeyError("No active session found.", sdkTypes.ZeroXKeyErrorCodes.NO_SESSION_FOUND);
1190
+ }
1191
+ const sessionKey = params?.sessionKey ?? activeSessionKey;
1192
+ const res = await utils.withZeroXKeyErrorHandling(() => client.refreshSession({ ...params }), () => logout(), callbacks, "Failed to refresh session");
1193
+ const session = await getSession({ sessionKey });
1194
+ if (session && sessionKey) {
1195
+ await scheduleSessionExpiration({
1196
+ sessionKey,
1197
+ expiry: session.expiry,
1198
+ ...(params?.expirationSeconds && {
1199
+ expirationSeconds: params?.expirationSeconds,
1200
+ }),
1201
+ });
1202
+ }
1203
+ const allSessions = await getAllSessions();
1204
+ setSession(session);
1205
+ setAllSessions(allSessions);
1206
+ return res;
1207
+ }, [client, callbacks, scheduleSessionExpiration, session, user, masterConfig]);
1208
+ const getSession = react.useCallback(async (params) => {
1209
+ if (!client)
1210
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1211
+ return utils.withZeroXKeyErrorHandling(() => client.getSession(params), () => logout(), callbacks, "Failed to get session");
1212
+ }, [client, callbacks, masterConfig, session, user]);
1213
+ const getAllSessions = react.useCallback(async () => {
1214
+ if (!client)
1215
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1216
+ return utils.withZeroXKeyErrorHandling(() => client.getAllSessions(), () => logout(), callbacks, "Failed to get all sessions");
1217
+ }, [client, callbacks, masterConfig, session, user]);
1218
+ const setActiveSession = react.useCallback(async (params) => {
1219
+ if (!client)
1220
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1221
+ const session = await utils.withZeroXKeyErrorHandling(() => client.getSession({ sessionKey: params.sessionKey }), () => logout(), callbacks, "Failed to get session");
1222
+ const s = await getSession();
1223
+ if (!s) {
1224
+ throw new sdkTypes.ZeroXKeyError("Session not found.", sdkTypes.ZeroXKeyErrorCodes.NOT_FOUND);
1225
+ }
1226
+ await utils.withZeroXKeyErrorHandling(() => client.setActiveSession(params), () => logout(), callbacks, "Failed to set active session");
1227
+ setSession(session);
1228
+ await utils.withZeroXKeyErrorHandling(async () => {
1229
+ await maybeRefreshWallets();
1230
+ await maybeRefreshUser();
1231
+ }, () => logout(), callbacks, "Failed to refresh data after setting active session");
1232
+ return;
1233
+ }, [client, callbacks, session, user, masterConfig]);
1234
+ const getActiveSessionKey = react.useCallback(async () => {
1235
+ if (!client)
1236
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1237
+ return utils.withZeroXKeyErrorHandling(() => client.getActiveSessionKey(), () => logout(), callbacks, "Failed to get active session key");
1238
+ }, [client, callbacks, masterConfig, session, user]);
1239
+ const clearUnusedKeyPairs = react.useCallback(async () => {
1240
+ if (!client)
1241
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1242
+ return utils.withZeroXKeyErrorHandling(() => client.clearUnusedKeyPairs(), () => logout(), callbacks, "Failed to clear unused key pairs");
1243
+ }, [client, callbacks, masterConfig, session, user]);
1244
+ const createApiKeyPair = react.useCallback(async (params) => {
1245
+ if (!client)
1246
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1247
+ return utils.withZeroXKeyErrorHandling(() => client.createApiKeyPair(params), () => logout(), callbacks, "Failed to create API key pair");
1248
+ }, [client, callbacks, session, user, masterConfig]);
1249
+ const getProxyAuthConfig = react.useCallback(async () => {
1250
+ if (!client)
1251
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1252
+ return utils.withZeroXKeyErrorHandling(() => client.getProxyAuthConfig(), () => logout(), callbacks, "Failed to get proxy auth config");
1253
+ }, [client, callbacks, masterConfig, session, user]);
1254
+ const verifyAppProofs = react.useCallback(async (params) => {
1255
+ if (!client)
1256
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1257
+ return utils.withZeroXKeyErrorHandling(() => client.verifyAppProofs(params), () => logout(), callbacks, "Failed to verify app proofs");
1258
+ }, [client, callbacks]);
1259
+ const refreshUser = react.useCallback(async (params) => {
1260
+ const { stampWith, organizationId, userId } = params || {};
1261
+ if (!client)
1262
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1263
+ const user = await utils.withZeroXKeyErrorHandling(() => fetchUser({
1264
+ stampWith,
1265
+ ...(organizationId && { organizationId }),
1266
+ ...(userId && { userId }),
1267
+ }), () => logout(), callbacks, "Failed to refresh user");
1268
+ if (user) {
1269
+ setUser(user);
1270
+ }
1271
+ }, [client, callbacks, fetchUser, session, user]);
1272
+ /**
1273
+ * @internal
1274
+ * Auto-refresh user only if enabled in config. This is only used internally.
1275
+ *
1276
+ * @param params.organizationId - organization ID to specify the sub-organization (defaults to the current session's organizationId).
1277
+ * @param params.userId - user ID to fetch specific user details (defaults to the current session's userId).
1278
+ * @param params.stampWith - parameter to stamp the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
1279
+ * @returns A promise that resolves when the user is refreshed, or does nothing if auto-refresh is disabled
1280
+ */
1281
+ const maybeRefreshUser = react.useCallback(async (params) => {
1282
+ if (!masterConfig?.autoRefreshManagedState)
1283
+ return;
1284
+ return refreshUser(params);
1285
+ }, [masterConfig, refreshUser]);
1286
+ const refreshWallets = react.useCallback(async (params) => {
1287
+ const { stampWith, organizationId, userId } = params || {};
1288
+ if (!client)
1289
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1290
+ const wallets = await utils.withZeroXKeyErrorHandling(() => fetchWallets({
1291
+ stampWith,
1292
+ ...(organizationId && { organizationId }),
1293
+ ...(userId && { userId }),
1294
+ }), () => logout(), callbacks, "Failed to refresh wallets");
1295
+ if (wallets) {
1296
+ setWallets(wallets);
1297
+ }
1298
+ return wallets;
1299
+ }, [client, callbacks, fetchWallets, session, user]);
1300
+ /**
1301
+ * @internal
1302
+ * Auto-refresh wallets only if enabled in config. This is only used internally.
1303
+ *
1304
+ * @param params.organizationId - organization ID to specify the sub-organization (defaults to the current session's organizationId).
1305
+ * @param params.userId - user ID to fetch specific user details (defaults to the current session's userId).
1306
+ * @param params.stampWith - parameter to stamp the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
1307
+ * @returns A promise that resolves to an array of wallets, or an empty array if auto-refresh is disabled
1308
+ */
1309
+ const maybeRefreshWallets = react.useCallback(async (params) => {
1310
+ if (!masterConfig?.autoRefreshManagedState)
1311
+ return [];
1312
+ return refreshWallets(params);
1313
+ }, [masterConfig, refreshWallets]);
1314
+ const handleDiscordOauth = react.useCallback(async (params) => {
1315
+ const { additionalState: additionalParameters } = params || {};
1316
+ const { clientId, redirectUri, appScheme: scheme, } = getOauthProviderSettings(sdkTypes.OAuthProviders.DISCORD);
1317
+ try {
1318
+ if (!masterConfig) {
1319
+ throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1320
+ }
1321
+ if (!clientId) {
1322
+ throw new sdkTypes.ZeroXKeyError("Discord Client ID is not configured.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1323
+ }
1324
+ if (!redirectUri) {
1325
+ throw new sdkTypes.ZeroXKeyError("OAuth Redirect URI is not configured.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1326
+ }
1327
+ if (!scheme) {
1328
+ throw new sdkTypes.ZeroXKeyError("Missing appScheme. Please set auth.oauth.appScheme.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1329
+ }
1330
+ // Create key pair and generate nonce
1331
+ const publicKey = await createApiKeyPair();
1332
+ if (!publicKey) {
1333
+ throw new sdkTypes.ZeroXKeyError("Failed to create public key for OAuth.", sdkTypes.ZeroXKeyErrorCodes.OAUTH_SIGNUP_ERROR);
1334
+ }
1335
+ const nonce = utils$1.bytesToHex(sha2.sha256(publicKey));
1336
+ // Generate PKCE challenge pair and store verifier
1337
+ const { verifier, codeChallenge } = await oauth.generateChallengePair();
1338
+ await oauth.storePKCEVerifier(sdkTypes.OAuthProviders.DISCORD, verifier);
1339
+ // Build OAuth URL (direct Discord URL, not proxy)
1340
+ const discordAuthUrl = oauth.buildOAuthUrl({
1341
+ provider: sdkTypes.OAuthProviders.DISCORD,
1342
+ clientId,
1343
+ redirectUri,
1344
+ publicKey,
1345
+ nonce,
1346
+ codeChallenge,
1347
+ additionalState: additionalParameters,
1348
+ useOauthProxyOrigin: false,
1349
+ });
1350
+ if (!(await reactNativeInappbrowserReborn.InAppBrowser.isAvailable())) {
1351
+ throw new sdkTypes.ZeroXKeyError("InAppBrowser is not available", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1352
+ }
1353
+ const result = await reactNativeInappbrowserReborn.InAppBrowser.openAuth(discordAuthUrl, scheme, {
1354
+ dismissButtonStyle: "cancel",
1355
+ animated: true,
1356
+ modalPresentationStyle: "fullScreen",
1357
+ modalTransitionStyle: "coverVertical",
1358
+ modalEnabled: true,
1359
+ enableBarCollapsing: false,
1360
+ showTitle: true,
1361
+ enableUrlBarHiding: true,
1362
+ enableDefaultShare: true,
1363
+ });
1364
+ if (!result || result.type !== "success" || !result.url) {
1365
+ throw new sdkTypes.ZeroXKeyError("OAuth flow did not complete successfully", sdkTypes.ZeroXKeyErrorCodes.OAUTH_SIGNUP_ERROR);
1366
+ }
1367
+ // Parse the deep link result
1368
+ const parsed = oauth.parseInAppBrowserResult(result.url);
1369
+ if (!parsed.authCode) {
1370
+ throw new sdkTypes.ZeroXKeyError("Missing authorization code from Discord OAuth", sdkTypes.ZeroXKeyErrorCodes.OAUTH_SIGNUP_ERROR);
1371
+ }
1372
+ // Handle PKCE flow: exchange code for token and complete
1373
+ await oauth.handlePKCEFlow({
1374
+ provider: sdkTypes.OAuthProviders.DISCORD,
1375
+ publicKey,
1376
+ authCode: parsed.authCode,
1377
+ ...(parsed.sessionKey && { sessionKey: parsed.sessionKey }),
1378
+ ...(callbacks && { callbacks }),
1379
+ completeOauth,
1380
+ exchangeCodeForToken: async (codeVerifier) => {
1381
+ const resp = await client?.httpClient?.proxyOAuth2Authenticate({
1382
+ provider: "OAUTH2_PROVIDER_DISCORD",
1383
+ authCode: parsed.authCode,
1384
+ redirectUri,
1385
+ codeVerifier,
1386
+ clientId,
1387
+ nonce,
1388
+ });
1389
+ const oidcToken = resp?.oidcToken;
1390
+ if (!oidcToken) {
1391
+ throw new sdkTypes.ZeroXKeyError("Missing oidcToken from OAuth exchange", sdkTypes.ZeroXKeyErrorCodes.OAUTH_SIGNUP_ERROR);
1392
+ }
1393
+ return oidcToken;
1394
+ },
1395
+ });
1396
+ return;
1397
+ }
1398
+ catch (error) {
1399
+ throw error;
1400
+ }
1401
+ }, [client, callbacks, masterConfig, session, user]);
1402
+ const handleXOauth = react.useCallback(async (params) => {
1403
+ const { additionalState: additionalParameters } = params || {};
1404
+ const { clientId, redirectUri, appScheme: scheme, } = getOauthProviderSettings(sdkTypes.OAuthProviders.X);
1405
+ try {
1406
+ if (!masterConfig) {
1407
+ throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1408
+ }
1409
+ if (!clientId) {
1410
+ throw new sdkTypes.ZeroXKeyError("Twitter Client ID is not configured.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1411
+ }
1412
+ if (!redirectUri) {
1413
+ throw new sdkTypes.ZeroXKeyError("OAuth Redirect URI is not configured.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1414
+ }
1415
+ if (!scheme) {
1416
+ throw new sdkTypes.ZeroXKeyError("Missing appScheme. Please set auth.oauth.appScheme.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1417
+ }
1418
+ const publicKey = await createApiKeyPair();
1419
+ if (!publicKey) {
1420
+ throw new sdkTypes.ZeroXKeyError("Failed to create public key for OAuth.", sdkTypes.ZeroXKeyErrorCodes.OAUTH_SIGNUP_ERROR);
1421
+ }
1422
+ const nonce = utils$1.bytesToHex(sha2.sha256(publicKey));
1423
+ // Generate PKCE challenge pair and store verifier
1424
+ const { verifier, codeChallenge } = await oauth.generateChallengePair();
1425
+ await oauth.storePKCEVerifier(sdkTypes.OAuthProviders.X, verifier);
1426
+ // Build OAuth URL (direct X/Twitter URL, not proxy)
1427
+ const twitterAuthUrl = oauth.buildOAuthUrl({
1428
+ provider: sdkTypes.OAuthProviders.X,
1429
+ clientId,
1430
+ redirectUri,
1431
+ publicKey,
1432
+ nonce,
1433
+ codeChallenge,
1434
+ additionalState: additionalParameters,
1435
+ useOauthProxyOrigin: false,
1436
+ });
1437
+ if (!(await reactNativeInappbrowserReborn.InAppBrowser.isAvailable())) {
1438
+ throw new sdkTypes.ZeroXKeyError("InAppBrowser is not available", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1439
+ }
1440
+ const result = await reactNativeInappbrowserReborn.InAppBrowser.openAuth(twitterAuthUrl, scheme, {
1441
+ dismissButtonStyle: "cancel",
1442
+ animated: true,
1443
+ modalPresentationStyle: "fullScreen",
1444
+ modalTransitionStyle: "coverVertical",
1445
+ modalEnabled: true,
1446
+ enableBarCollapsing: false,
1447
+ showTitle: true,
1448
+ enableUrlBarHiding: true,
1449
+ enableDefaultShare: true,
1450
+ });
1451
+ if (!result || result.type !== "success" || !result.url) {
1452
+ throw new sdkTypes.ZeroXKeyError("OAuth flow did not complete successfully", sdkTypes.ZeroXKeyErrorCodes.OAUTH_SIGNUP_ERROR);
1453
+ }
1454
+ // Parse the deep link result
1455
+ const parsed = oauth.parseInAppBrowserResult(result.url);
1456
+ if (!parsed.authCode) {
1457
+ throw new sdkTypes.ZeroXKeyError("Missing authorization code from Twitter OAuth", sdkTypes.ZeroXKeyErrorCodes.OAUTH_SIGNUP_ERROR);
1458
+ }
1459
+ // Handle PKCE flow: exchange code for token and complete
1460
+ await oauth.handlePKCEFlow({
1461
+ provider: sdkTypes.OAuthProviders.X,
1462
+ publicKey,
1463
+ authCode: parsed.authCode,
1464
+ ...(parsed.sessionKey && { sessionKey: parsed.sessionKey }),
1465
+ ...(callbacks && { callbacks }),
1466
+ completeOauth,
1467
+ exchangeCodeForToken: async (codeVerifier) => {
1468
+ const resp = await client?.httpClient?.proxyOAuth2Authenticate({
1469
+ provider: "OAUTH2_PROVIDER_X",
1470
+ authCode: parsed.authCode,
1471
+ redirectUri,
1472
+ codeVerifier,
1473
+ clientId,
1474
+ nonce,
1475
+ });
1476
+ const oidcToken = resp?.oidcToken;
1477
+ if (!oidcToken) {
1478
+ throw new sdkTypes.ZeroXKeyError("Missing oidcToken from OAuth exchange", sdkTypes.ZeroXKeyErrorCodes.OAUTH_SIGNUP_ERROR);
1479
+ }
1480
+ return oidcToken;
1481
+ },
1482
+ });
1483
+ return;
1484
+ }
1485
+ catch (error) {
1486
+ throw error;
1487
+ }
1488
+ }, [client, callbacks, masterConfig, session, user]);
1489
+ const handleGoogleOauth = react.useCallback(async (params) => {
1490
+ const { clientId, redirectUri, appScheme: scheme, } = getOauthProviderSettings(sdkTypes.OAuthProviders.GOOGLE);
1491
+ try {
1492
+ if (!masterConfig) {
1493
+ throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1494
+ }
1495
+ if (!clientId) {
1496
+ throw new sdkTypes.ZeroXKeyError("Google Client ID is not configured.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1497
+ }
1498
+ if (!redirectUri) {
1499
+ throw new sdkTypes.ZeroXKeyError("OAuth Redirect URI is not configured.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1500
+ }
1501
+ if (!scheme) {
1502
+ throw new sdkTypes.ZeroXKeyError("Missing appScheme. Please set auth.oauth.appScheme.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1503
+ }
1504
+ const finalRedirectUri = `${redirectUri}?scheme=${encodeURIComponent(scheme)}`;
1505
+ // Create key pair and generate nonce
1506
+ const publicKey = await createApiKeyPair();
1507
+ if (!publicKey) {
1508
+ throw new sdkTypes.ZeroXKeyError("Failed to create public key for OAuth.", sdkTypes.ZeroXKeyErrorCodes.OAUTH_SIGNUP_ERROR);
1509
+ }
1510
+ const nonce = utils$1.bytesToHex(sha2.sha256(publicKey));
1511
+ // Build OAuth URL using ZeroXKey OAuth proxy
1512
+ const oauthUrl = oauth.buildOAuthUrl({
1513
+ provider: sdkTypes.OAuthProviders.GOOGLE,
1514
+ clientId,
1515
+ redirectUri: finalRedirectUri,
1516
+ publicKey,
1517
+ nonce,
1518
+ useOauthProxyOrigin: true,
1519
+ });
1520
+ if (!(await reactNativeInappbrowserReborn.InAppBrowser.isAvailable())) {
1521
+ throw new sdkTypes.ZeroXKeyError("InAppBrowser is not available", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1522
+ }
1523
+ const result = await reactNativeInappbrowserReborn.InAppBrowser.openAuth(oauthUrl, scheme, {
1524
+ dismissButtonStyle: "cancel",
1525
+ animated: true,
1526
+ modalPresentationStyle: "fullScreen",
1527
+ modalTransitionStyle: "coverVertical",
1528
+ modalEnabled: true,
1529
+ enableBarCollapsing: false,
1530
+ showTitle: true,
1531
+ enableUrlBarHiding: true,
1532
+ enableDefaultShare: true,
1533
+ });
1534
+ if (!result || result.type !== "success" || !result.url) {
1535
+ throw new sdkTypes.ZeroXKeyError("OAuth flow did not complete successfully", sdkTypes.ZeroXKeyErrorCodes.OAUTH_SIGNUP_ERROR);
1536
+ }
1537
+ // Parse the deep link result
1538
+ const parsed = oauth.parseInAppBrowserResult(result.url);
1539
+ if (!parsed.idToken) {
1540
+ throw new sdkTypes.ZeroXKeyError("oidcToken not found in the response", sdkTypes.ZeroXKeyErrorCodes.OAUTH_SIGNUP_ERROR);
1541
+ }
1542
+ // Complete OAuth flow
1543
+ await oauth.completeOAuthFlow({
1544
+ provider: sdkTypes.OAuthProviders.GOOGLE,
1545
+ publicKey,
1546
+ oidcToken: parsed.idToken,
1547
+ ...(parsed.sessionKey && { sessionKey: parsed.sessionKey }),
1548
+ ...(callbacks && { callbacks }),
1549
+ completeOauth,
1550
+ });
1551
+ return;
1552
+ }
1553
+ catch (error) {
1554
+ throw error;
1555
+ }
1556
+ }, [client, callbacks, masterConfig, session, user]);
1557
+ const handleAppleOauth = react.useCallback(async (params) => {
1558
+ const { additionalState: additionalParameters } = params || {};
1559
+ const { clientId, redirectUri, appScheme: scheme, } = getOauthProviderSettings(sdkTypes.OAuthProviders.APPLE);
1560
+ try {
1561
+ if (!masterConfig) {
1562
+ throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1563
+ }
1564
+ if (!clientId) {
1565
+ throw new sdkTypes.ZeroXKeyError("Apple Client ID is not configured.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1566
+ }
1567
+ if (!redirectUri) {
1568
+ throw new sdkTypes.ZeroXKeyError("OAuth Redirect URI is not configured.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1569
+ }
1570
+ if (!scheme) {
1571
+ throw new sdkTypes.ZeroXKeyError("Missing appScheme. Please set auth.oauth.appScheme.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1572
+ }
1573
+ const finalRedirectUri = `${redirectUri}?scheme=${encodeURIComponent(scheme)}`;
1574
+ // Create key pair and generate nonce
1575
+ const publicKey = await createApiKeyPair();
1576
+ if (!publicKey) {
1577
+ throw new sdkTypes.ZeroXKeyError("Failed to create public key for OAuth.", sdkTypes.ZeroXKeyErrorCodes.OAUTH_SIGNUP_ERROR);
1578
+ }
1579
+ const nonce = utils$1.bytesToHex(sha2.sha256(publicKey));
1580
+ // Build OAuth URL using ZeroXKey OAuth proxy
1581
+ const oauthUrl = oauth.buildOAuthUrl({
1582
+ provider: sdkTypes.OAuthProviders.APPLE,
1583
+ clientId,
1584
+ redirectUri: finalRedirectUri,
1585
+ publicKey,
1586
+ nonce,
1587
+ additionalState: additionalParameters,
1588
+ useOauthProxyOrigin: true,
1589
+ });
1590
+ if (!(await reactNativeInappbrowserReborn.InAppBrowser.isAvailable())) {
1591
+ throw new sdkTypes.ZeroXKeyError("InAppBrowser is not available", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1592
+ }
1593
+ const result = await reactNativeInappbrowserReborn.InAppBrowser.openAuth(oauthUrl, scheme, {
1594
+ dismissButtonStyle: "cancel",
1595
+ animated: true,
1596
+ modalPresentationStyle: "fullScreen",
1597
+ modalTransitionStyle: "coverVertical",
1598
+ modalEnabled: true,
1599
+ enableBarCollapsing: false,
1600
+ showTitle: true,
1601
+ enableUrlBarHiding: true,
1602
+ enableDefaultShare: true,
1603
+ });
1604
+ if (!result || result.type !== "success" || !result.url) {
1605
+ throw new sdkTypes.ZeroXKeyError("OAuth flow did not complete successfully", sdkTypes.ZeroXKeyErrorCodes.OAUTH_SIGNUP_ERROR);
1606
+ }
1607
+ // Parse the deep link result
1608
+ const parsed = oauth.parseInAppBrowserResult(result.url);
1609
+ if (!parsed.idToken) {
1610
+ throw new sdkTypes.ZeroXKeyError("oidcToken not found in the response", sdkTypes.ZeroXKeyErrorCodes.OAUTH_SIGNUP_ERROR);
1611
+ }
1612
+ // Complete OAuth flow
1613
+ await oauth.completeOAuthFlow({
1614
+ provider: sdkTypes.OAuthProviders.APPLE,
1615
+ publicKey,
1616
+ oidcToken: parsed.idToken,
1617
+ ...(parsed.sessionKey && { sessionKey: parsed.sessionKey }),
1618
+ ...(callbacks && { callbacks }),
1619
+ completeOauth,
1620
+ });
1621
+ return;
1622
+ }
1623
+ catch (error) {
1624
+ throw error;
1625
+ }
1626
+ }, [client, callbacks, masterConfig, session, user]);
1627
+ const handleFacebookOauth = react.useCallback(async (params) => {
1628
+ const { additionalState: additionalParameters } = params || {};
1629
+ const { clientId, redirectUri, appScheme: scheme, } = getOauthProviderSettings(sdkTypes.OAuthProviders.FACEBOOK);
1630
+ try {
1631
+ if (!masterConfig) {
1632
+ throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1633
+ }
1634
+ if (!clientId) {
1635
+ throw new sdkTypes.ZeroXKeyError("Facebook Client ID is not configured.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1636
+ }
1637
+ if (!redirectUri) {
1638
+ throw new sdkTypes.ZeroXKeyError("OAuth Redirect URI is not configured.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1639
+ }
1640
+ if (!scheme) {
1641
+ throw new sdkTypes.ZeroXKeyError("Missing appScheme. Please set auth.oauth.appScheme.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1642
+ }
1643
+ const finalRedirectUri = `${redirectUri}?scheme=${encodeURIComponent(scheme)}`;
1644
+ // Create key pair and generate nonce
1645
+ const publicKey = await createApiKeyPair();
1646
+ if (!publicKey) {
1647
+ throw new sdkTypes.ZeroXKeyError("Failed to create public key for OAuth.", sdkTypes.ZeroXKeyErrorCodes.OAUTH_SIGNUP_ERROR);
1648
+ }
1649
+ const nonce = utils$1.bytesToHex(sha2.sha256(publicKey));
1650
+ // Generate PKCE challenge pair and store verifier
1651
+ const { verifier, codeChallenge } = await oauth.generateChallengePair();
1652
+ await oauth.storePKCEVerifier(sdkTypes.OAuthProviders.FACEBOOK, verifier);
1653
+ // Build OAuth URL using ZeroXKey OAuth proxy
1654
+ const oauthUrl = oauth.buildOAuthUrl({
1655
+ provider: sdkTypes.OAuthProviders.FACEBOOK,
1656
+ clientId,
1657
+ redirectUri: finalRedirectUri,
1658
+ publicKey,
1659
+ nonce,
1660
+ codeChallenge,
1661
+ additionalState: additionalParameters,
1662
+ useOauthProxyOrigin: true,
1663
+ });
1664
+ if (!(await reactNativeInappbrowserReborn.InAppBrowser.isAvailable())) {
1665
+ throw new sdkTypes.ZeroXKeyError("InAppBrowser is not available", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1666
+ }
1667
+ const result = await reactNativeInappbrowserReborn.InAppBrowser.openAuth(oauthUrl, scheme, {
1668
+ dismissButtonStyle: "cancel",
1669
+ animated: true,
1670
+ modalPresentationStyle: "fullScreen",
1671
+ modalTransitionStyle: "coverVertical",
1672
+ modalEnabled: true,
1673
+ enableBarCollapsing: false,
1674
+ showTitle: true,
1675
+ enableUrlBarHiding: true,
1676
+ enableDefaultShare: true,
1677
+ });
1678
+ if (!result || result.type !== "success" || !result.url) {
1679
+ throw new sdkTypes.ZeroXKeyError("OAuth flow did not complete successfully", sdkTypes.ZeroXKeyErrorCodes.OAUTH_SIGNUP_ERROR);
1680
+ }
1681
+ // Parse the deep link result
1682
+ const parsed = oauth.parseInAppBrowserResult(result.url);
1683
+ if (!parsed.authCode) {
1684
+ throw new sdkTypes.ZeroXKeyError("Missing authorization code from Facebook OAuth", sdkTypes.ZeroXKeyErrorCodes.OAUTH_SIGNUP_ERROR);
1685
+ }
1686
+ // Handle PKCE flow: exchange code for token and complete
1687
+ await oauth.handlePKCEFlow({
1688
+ provider: sdkTypes.OAuthProviders.FACEBOOK,
1689
+ publicKey,
1690
+ authCode: parsed.authCode,
1691
+ ...(parsed.sessionKey && { sessionKey: parsed.sessionKey }),
1692
+ ...(callbacks && { callbacks }),
1693
+ completeOauth,
1694
+ exchangeCodeForToken: async (codeVerifier) => {
1695
+ const tokenData = await oauth.exchangeCodeForToken(clientId, finalRedirectUri, parsed.authCode, codeVerifier);
1696
+ const idToken = tokenData?.id_token;
1697
+ if (!idToken) {
1698
+ throw new sdkTypes.ZeroXKeyError("Missing oidcToken from OAuth exchange", sdkTypes.ZeroXKeyErrorCodes.OAUTH_SIGNUP_ERROR);
1699
+ }
1700
+ return idToken;
1701
+ },
1702
+ });
1703
+ return;
1704
+ }
1705
+ catch (error) {
1706
+ throw error;
1707
+ }
1708
+ }, [client, callbacks, masterConfig, session, user]);
1709
+ react.useEffect(() => {
1710
+ if (proxyAuthConfigRef.current)
1711
+ return;
1712
+ // Only fetch the proxy auth config once. Use that to build the master config.
1713
+ const fetchProxyAuthConfig = async () => {
1714
+ try {
1715
+ let proxyAuthConfig;
1716
+ if (shouldFetchWalletKitConfig) {
1717
+ // Only fetch the proxy auth config if we have an authProxyId and the autoFetchWalletKitConfig param is enabled or not passed in.
1718
+ const sanitizedAuthProxyUrl = config.authProxyUrl && config.authProxyUrl.trim()
1719
+ ? config.authProxyUrl
1720
+ : undefined;
1721
+ proxyAuthConfig = await core.getAuthProxyConfig(config.authProxyConfigId, // Can assert safely. See shouldFetchWalletKitConfig definition.
1722
+ sanitizedAuthProxyUrl);
1723
+ proxyAuthConfigRef.current = proxyAuthConfig;
1724
+ }
1725
+ setMasterConfig(buildConfig(proxyAuthConfig));
1726
+ }
1727
+ catch {
1728
+ setClientState(base.ClientState.Error);
1729
+ }
1730
+ };
1731
+ fetchProxyAuthConfig();
1732
+ }, []);
1733
+ react.useEffect(() => {
1734
+ // Start the client initialization process once we have the master config.
1735
+ if (!masterConfig)
1736
+ return;
1737
+ initializeClient();
1738
+ }, [masterConfig]);
1739
+ react.useEffect(() => {
1740
+ // Handle changes to the passed in config prop -- update the master config
1741
+ // Rebuild the master config with the updated config and stored proxyAuthConfig
1742
+ // If we don't have a stored proxyAuthConfig and we need to fetch it, we wait until that fetch is done in the other useEffect.
1743
+ // If shouldFetchWalletKitConfig is false, we'll never have a proxyAuthConfig to build the master config with, so this useEffect should always run.
1744
+ if (!proxyAuthConfigRef.current && shouldFetchWalletKitConfig)
1745
+ return;
1746
+ setMasterConfig(buildConfig(proxyAuthConfigRef.current ?? undefined));
1747
+ }, [config, proxyAuthConfigRef.current]);
1748
+ react.useEffect(() => {
1749
+ // authState must be consistent with session state. We found during testing that there are cases where the session and authState can be out of sync in very rare edge cases.
1750
+ // This will ensure that they are always in sync and remove the need to setAuthState manually in other places.
1751
+ if (session && utils.isValidSession(session)) {
1752
+ setAuthState(base.AuthState.Authenticated);
1753
+ }
1754
+ else {
1755
+ setAuthState(base.AuthState.Unauthenticated);
1756
+ }
1757
+ }, [session]);
1758
+ react.useEffect(() => {
1759
+ // After client and config are ready, initialize sessions then mark client ready.
1760
+ if (!client || !masterConfig)
1761
+ return;
1762
+ clearSessionTimeouts();
1763
+ initializeSessions().finally(() => {
1764
+ setClientState(base.ClientState.Ready);
1765
+ });
1766
+ return () => {
1767
+ clearSessionTimeouts();
1768
+ };
1769
+ }, [client]);
1770
+ return (jsxRuntime.jsx(Types.ClientContext.Provider, { value: {
1771
+ session,
1772
+ allSessions,
1773
+ clientState,
1774
+ authState,
1775
+ user,
1776
+ wallets,
1777
+ config: masterConfig,
1778
+ httpClient: client?.httpClient,
1779
+ createHttpClient,
1780
+ createPasskey,
1781
+ logout,
1782
+ loginWithPasskey,
1783
+ signUpWithPasskey,
1784
+ initOtp,
1785
+ verifyOtp,
1786
+ loginWithOtp,
1787
+ signUpWithOtp,
1788
+ completeOtp,
1789
+ loginWithOauth,
1790
+ signUpWithOauth,
1791
+ completeOauth,
1792
+ fetchWallets,
1793
+ fetchWalletAccounts,
1794
+ fetchPrivateKeys,
1795
+ verifyAppProofs,
1796
+ refreshWallets,
1797
+ signMessage,
1798
+ signTransaction,
1799
+ signAndSendTransaction,
1800
+ ethSendTransaction,
1801
+ ethSendErc20Transfer,
1802
+ solSendTransaction,
1803
+ pollTransactionStatus,
1804
+ fetchUser,
1805
+ fetchOrCreateP256ApiKeyUser,
1806
+ fetchOrCreatePolicies,
1807
+ refreshUser,
1808
+ updateUserEmail,
1809
+ removeUserEmail,
1810
+ updateUserPhoneNumber,
1811
+ removeUserPhoneNumber,
1812
+ updateUserName,
1813
+ addOauthProvider,
1814
+ removeOauthProviders,
1815
+ addPasskey,
1816
+ removePasskeys,
1817
+ createWallet,
1818
+ createWalletAccounts,
1819
+ exportWallet,
1820
+ exportPrivateKey,
1821
+ exportWalletAccount,
1822
+ importWallet,
1823
+ importPrivateKey,
1824
+ deleteSubOrganization,
1825
+ storeSession,
1826
+ clearSession,
1827
+ clearAllSessions,
1828
+ refreshSession,
1829
+ getSession,
1830
+ getAllSessions,
1831
+ setActiveSession,
1832
+ clearUnusedKeyPairs,
1833
+ getActiveSessionKey,
1834
+ createApiKeyPair,
1835
+ getProxyAuthConfig,
1836
+ handleGoogleOauth,
1837
+ handleXOauth,
1838
+ handleDiscordOauth,
1839
+ handleAppleOauth,
1840
+ handleFacebookOauth,
1841
+ fetchBootProofForAppProof,
1842
+ }, children: children }));
1843
+ };
1844
+
1845
+ exports.ZeroXKeyProvider = ZeroXKeyProvider;
1846
+ //# sourceMappingURL=ZeroXKeyProvider.js.map