@openfort/react-native 0.1.20 → 0.1.21

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 (43) hide show
  1. package/dist/components/AuthBoundary.js +4 -1
  2. package/dist/core/index.js +1 -1
  3. package/dist/core/provider.js +0 -1
  4. package/dist/hooks/auth/useEmailAuth.js +90 -3
  5. package/dist/hooks/core/useOpenfort.js +3 -17
  6. package/dist/hooks/wallet/index.js +4 -2
  7. package/dist/hooks/wallet/solanaProvider.js +77 -0
  8. package/dist/hooks/wallet/useEmbeddedEthereumWallet.js +465 -0
  9. package/dist/hooks/wallet/useEmbeddedSolanaWallet.js +391 -0
  10. package/dist/hooks/wallet/utils.js +75 -0
  11. package/dist/lib/hookConsistency.js +6 -0
  12. package/dist/native/oauth.js +13 -0
  13. package/dist/native/storage.js +4 -0
  14. package/dist/native/webview.js +15 -1
  15. package/dist/types/components/AuthBoundary.d.ts +1 -0
  16. package/dist/types/core/index.d.ts +1 -1
  17. package/dist/types/hooks/auth/useEmailAuth.d.ts +6 -7
  18. package/dist/types/hooks/auth/useGuestAuth.d.ts +1 -2
  19. package/dist/types/hooks/auth/useOAuth.d.ts +1 -2
  20. package/dist/types/hooks/core/useOpenfort.d.ts +2 -13
  21. package/dist/types/hooks/wallet/index.d.ts +2 -1
  22. package/dist/types/hooks/wallet/solanaProvider.d.ts +75 -0
  23. package/dist/types/hooks/wallet/useEmbeddedEthereumWallet.d.ts +53 -0
  24. package/dist/types/hooks/wallet/useEmbeddedSolanaWallet.d.ts +47 -0
  25. package/dist/types/hooks/wallet/utils.d.ts +17 -0
  26. package/dist/types/index.js +1 -2
  27. package/dist/types/lib/hookConsistency.d.ts +6 -0
  28. package/dist/types/native/oauth.d.ts +13 -0
  29. package/dist/types/native/storage.d.ts +4 -0
  30. package/dist/types/native/webview.d.ts +14 -0
  31. package/dist/types/types/auth.d.ts +0 -41
  32. package/dist/types/types/index.d.ts +3 -30
  33. package/dist/types/types/oauth.d.ts +0 -38
  34. package/dist/types/types/wallet.d.ts +120 -216
  35. package/package.json +1 -1
  36. package/dist/hooks/auth/useCreateWalletPostAuth.js +0 -34
  37. package/dist/hooks/wallet/useWallets.js +0 -436
  38. package/dist/types/config.js +0 -1
  39. package/dist/types/hooks/auth/useCreateWalletPostAuth.d.ts +0 -1
  40. package/dist/types/hooks/wallet/useWallets.d.ts +0 -78
  41. package/dist/types/predicates.js +0 -120
  42. package/dist/types/types/config.d.ts +0 -39
  43. package/dist/types/types/predicates.d.ts +0 -118
@@ -0,0 +1,391 @@
1
+ import { AccountTypeEnum, ChainTypeEnum, EmbeddedState } from '@openfort/openfort-js';
2
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
+ import { useOpenfortContext } from '../../core/context';
4
+ import { onError, onSuccess } from '../../lib/hookConsistency';
5
+ import { logger } from '../../lib/logger';
6
+ import { OpenfortError, OpenfortErrorType } from '../../types/openfortError';
7
+ import { OpenfortSolanaProvider } from './solanaProvider';
8
+ import { buildRecoveryParams } from './utils';
9
+ /**
10
+ * Hook for managing embedded Solana wallets.
11
+ *
12
+ * This hook provides comprehensive Solana wallet management including creation, activation,
13
+ * and recovery. It returns a discriminated union state that enables type-safe wallet interactions.
14
+ *
15
+ * @param options - Configuration with callback functions
16
+ * @returns Discriminated union state object. The `status` field determines available properties.
17
+ * Possible states: 'disconnected', 'connecting', 'reconnecting', 'creating', 'needs-recovery',
18
+ * 'connected', 'error'. When connected, includes `provider` and `activeWallet`. All states include
19
+ * `create`, `setActive`, and `wallets` methods/properties.
20
+ *
21
+ * @example
22
+ * ```tsx
23
+ * import { useEmbeddedSolanaWallet, isConnected, isLoading } from '@openfort/react-native';
24
+ *
25
+ * const solana = useEmbeddedSolanaWallet({
26
+ * onCreateSuccess: (account, provider) => console.log('Wallet created:', account.address),
27
+ * });
28
+ *
29
+ * if (isLoading(solana)) {
30
+ * return <ActivityIndicator />;
31
+ * }
32
+ *
33
+ * if (isConnected(solana)) {
34
+ * // TypeScript knows provider and activeWallet are available
35
+ * const signed = await solana.provider.signTransaction(transaction);
36
+ * const publicKey = solana.provider.publicKey;
37
+ * }
38
+ *
39
+ * // Create wallet if none exist
40
+ * if (solana.status === 'disconnected' && solana.wallets.length === 0) {
41
+ * await solana.create({ recoveryMethod: 'automatic' });
42
+ * }
43
+ * ```
44
+ */
45
+ export function useEmbeddedSolanaWallet(options = {}) {
46
+ const { client, walletConfig, embeddedState } = useOpenfortContext();
47
+ const [embeddedAccounts, setEmbeddedAccounts] = useState([]);
48
+ const [activeWalletId, setActiveWalletId] = useState(null);
49
+ const [activeAccount, setActiveAccount] = useState(null);
50
+ const [provider, setProvider] = useState(null);
51
+ const recoverPromiseRef = useRef(null);
52
+ const [status, setStatus] = useState({
53
+ status: 'idle',
54
+ });
55
+ // Fetch Solana embedded accounts
56
+ const fetchEmbeddedAccounts = useCallback(async () => {
57
+ if (!client || embeddedState === EmbeddedState.NONE || embeddedState === EmbeddedState.UNAUTHENTICATED) {
58
+ setEmbeddedAccounts([]);
59
+ return;
60
+ }
61
+ try {
62
+ const accounts = await client.embeddedWallet.list({
63
+ chainType: ChainTypeEnum.SVM,
64
+ accountType: AccountTypeEnum.EOA,
65
+ limit: 100,
66
+ });
67
+ setEmbeddedAccounts(accounts);
68
+ }
69
+ catch {
70
+ setEmbeddedAccounts([]);
71
+ }
72
+ }, [client, embeddedState]);
73
+ useEffect(() => {
74
+ fetchEmbeddedAccounts();
75
+ }, [fetchEmbeddedAccounts]);
76
+ // Sync active wallet ID and account with client
77
+ useEffect(() => {
78
+ ;
79
+ (async () => {
80
+ try {
81
+ const embeddedAccount = await client.embeddedWallet.get();
82
+ // here we check in case the current account is not SVM
83
+ if (embeddedAccount.chainType === ChainTypeEnum.SVM) {
84
+ setActiveWalletId(embeddedAccount.id);
85
+ setActiveAccount(embeddedAccount);
86
+ }
87
+ else {
88
+ setActiveWalletId(null);
89
+ setActiveAccount(null);
90
+ }
91
+ }
92
+ catch {
93
+ setActiveWalletId(null);
94
+ setActiveAccount(null);
95
+ }
96
+ })();
97
+ }, [client]);
98
+ // Get Solana provider
99
+ const getSolanaProvider = useCallback(async (account) => {
100
+ // Helper function to sign a single transaction
101
+ const signSingleTransaction = async (transaction) => {
102
+ // Extract the message bytes from the transaction
103
+ // For @solana/kit compiledTransaction, the messageBytes property contains what needs to be signed
104
+ let messageBytes;
105
+ if (transaction.messageBytes) {
106
+ // @solana/kit compiled transaction
107
+ messageBytes = transaction.messageBytes;
108
+ }
109
+ else if (transaction.serializeMessage) {
110
+ // @solana/web3.js Transaction
111
+ messageBytes = transaction.serializeMessage();
112
+ }
113
+ else if (transaction instanceof Uint8Array) {
114
+ // Raw bytes
115
+ messageBytes = transaction;
116
+ }
117
+ else {
118
+ throw new OpenfortError('Unsupported transaction format. Expected @solana/kit compiled transaction, @solana/web3.js Transaction, or Uint8Array', OpenfortErrorType.WALLET_ERROR);
119
+ }
120
+ // Convert Uint8Array to Buffer JSON format for React Native WebView serialization
121
+ // This is necessary because React Native's postMessage only accepts strings,
122
+ // and Uint8Array serializes incorrectly as {0:1, 1:2, ...} instead of {type:"Buffer", data:[...]}
123
+ const bufferFormatMessage = {
124
+ type: 'Buffer',
125
+ data: Array.from(messageBytes),
126
+ };
127
+ // Sign the message bytes (hashMessage: false for Solana - Ed25519 signs raw bytes)
128
+ // Note: We cast to any because the iframe will deserialize the Buffer format correctly,
129
+ // but TypeScript doesn't know about this serialization detail
130
+ const signatureBase58 = await client.embeddedWallet.signMessage(bufferFormatMessage, {
131
+ hashMessage: false,
132
+ });
133
+ // Return the signature in the expected format
134
+ // Different libraries expect different return formats, so we return a flexible object
135
+ return {
136
+ signature: signatureBase58,
137
+ publicKey: account.address,
138
+ };
139
+ };
140
+ const provider = new OpenfortSolanaProvider({
141
+ account,
142
+ signTransaction: signSingleTransaction,
143
+ signAllTransactions: async (transactions) => {
144
+ // Sign each transaction sequentially
145
+ const signedTransactions = [];
146
+ for (const transaction of transactions) {
147
+ const signed = await signSingleTransaction(transaction);
148
+ signedTransactions.push(signed);
149
+ }
150
+ return signedTransactions;
151
+ },
152
+ signMessage: async (message) => {
153
+ // Sign message using openfort-js (with hashMessage: false for Solana)
154
+ const result = await client.embeddedWallet.signMessage(message, { hashMessage: false });
155
+ return result;
156
+ },
157
+ });
158
+ return provider;
159
+ }, [client.embeddedWallet]);
160
+ // Initialize provider when recovering an active wallet on mount
161
+ useEffect(() => {
162
+ // Only initialize if we have an account but no provider
163
+ if (!activeAccount || provider) {
164
+ return;
165
+ }
166
+ // Don't interfere with user-initiated actions
167
+ if (['creating', 'connecting', 'reconnecting', 'loading'].includes(status.status)) {
168
+ return;
169
+ }
170
+ // Only initialize if embedded state is ready
171
+ if (embeddedState !== EmbeddedState.READY) {
172
+ return;
173
+ }
174
+ ;
175
+ (async () => {
176
+ try {
177
+ logger.info('Initializing provider for recovered Solana wallet session');
178
+ setStatus({ status: 'connecting' });
179
+ const solProvider = await getSolanaProvider(activeAccount);
180
+ setProvider(solProvider);
181
+ setStatus({ status: 'success' });
182
+ }
183
+ catch (e) {
184
+ const error = e instanceof OpenfortError
185
+ ? e
186
+ : new OpenfortError('Failed to initialize provider for active Solana wallet', OpenfortErrorType.WALLET_ERROR, { error: e });
187
+ logger.error('Solana provider initialization failed', error);
188
+ setStatus({ status: 'error', error });
189
+ }
190
+ })();
191
+ }, [activeAccount, provider, embeddedState, status.status, getSolanaProvider]);
192
+ // Build wallets list (simple deduplication by address)
193
+ const wallets = useMemo(() => {
194
+ return embeddedAccounts.map((account, index) => ({
195
+ address: account.address,
196
+ chainType: ChainTypeEnum.SVM,
197
+ walletIndex: index,
198
+ getProvider: async () => await getSolanaProvider(account),
199
+ }));
200
+ }, [embeddedAccounts, getSolanaProvider]);
201
+ // Create wallet action
202
+ const create = useCallback(async (createOptions) => {
203
+ logger.info('Creating Solana wallet with options', createOptions);
204
+ try {
205
+ setStatus({ status: 'creating' });
206
+ // Build recovery params (only use recoveryPassword, ignore createAdditional)
207
+ const recoveryParams = await buildRecoveryParams(createOptions?.recoveryPassword ? { recoveryPassword: createOptions.recoveryPassword } : undefined, walletConfig);
208
+ // Create embedded wallet
209
+ const embeddedAccount = await client.embeddedWallet.create({
210
+ chainType: ChainTypeEnum.SVM,
211
+ recoveryParams,
212
+ accountType: AccountTypeEnum.EOA, // Solana wallets are EOA
213
+ });
214
+ logger.info('Embedded Solana wallet created');
215
+ // Get provider
216
+ const solProvider = await getSolanaProvider(embeddedAccount);
217
+ setProvider(solProvider);
218
+ // Refresh accounts and set as active
219
+ await fetchEmbeddedAccounts();
220
+ setActiveWalletId(embeddedAccount.id);
221
+ setActiveAccount(embeddedAccount);
222
+ setStatus({ status: 'success' });
223
+ onSuccess({
224
+ options: createOptions,
225
+ data: {
226
+ account: embeddedAccount,
227
+ provider: solProvider,
228
+ },
229
+ });
230
+ if (createOptions?.onSuccess) {
231
+ createOptions.onSuccess({ account: embeddedAccount, provider: solProvider });
232
+ }
233
+ if (options.onCreateSuccess) {
234
+ options.onCreateSuccess(embeddedAccount, solProvider);
235
+ }
236
+ return embeddedAccount;
237
+ }
238
+ catch (e) {
239
+ const error = e instanceof OpenfortError
240
+ ? e
241
+ : new OpenfortError('Failed to create Solana wallet', OpenfortErrorType.WALLET_ERROR, { error: e });
242
+ setStatus({ status: 'error', error });
243
+ onError({
244
+ options: createOptions,
245
+ error,
246
+ });
247
+ if (createOptions?.onError) {
248
+ createOptions.onError(error);
249
+ }
250
+ if (options.onCreateError) {
251
+ options.onCreateError(error);
252
+ }
253
+ throw error;
254
+ }
255
+ }, [client, walletConfig, options, getSolanaProvider, fetchEmbeddedAccounts]);
256
+ // Set active wallet action
257
+ const setActive = useCallback(async (setActiveOptions) => {
258
+ // Prevent concurrent recoveries
259
+ if (recoverPromiseRef.current) {
260
+ await recoverPromiseRef.current;
261
+ return;
262
+ }
263
+ if (wallets.length === 0) {
264
+ const error = new OpenfortError('No embedded Solana wallets available to set as active', OpenfortErrorType.WALLET_ERROR);
265
+ onError({
266
+ options: setActiveOptions,
267
+ error,
268
+ });
269
+ if (setActiveOptions.onError) {
270
+ setActiveOptions.onError(error);
271
+ }
272
+ if (options.onSetActiveError) {
273
+ options.onSetActiveError(error);
274
+ }
275
+ throw error;
276
+ }
277
+ setStatus({ status: 'connecting' });
278
+ recoverPromiseRef.current = (async () => {
279
+ try {
280
+ // Find account to recover by address only
281
+ const embeddedAccountToRecover = embeddedAccounts.find((account) => account.address.toLowerCase() === setActiveOptions.address.toLowerCase());
282
+ if (!embeddedAccountToRecover) {
283
+ throw new OpenfortError(`No embedded Solana account found for address ${setActiveOptions.address}`, OpenfortErrorType.WALLET_ERROR);
284
+ }
285
+ // Build recovery params
286
+ const recoveryParams = await buildRecoveryParams(setActiveOptions, walletConfig);
287
+ // Recover the embedded wallet
288
+ const embeddedAccount = await client.embeddedWallet.recover({
289
+ account: embeddedAccountToRecover.id,
290
+ recoveryParams,
291
+ });
292
+ // Get provider
293
+ const solProvider = await getSolanaProvider(embeddedAccount);
294
+ setProvider(solProvider);
295
+ // Find the wallet index in the accounts list
296
+ const walletIndex = embeddedAccounts.findIndex((acc) => acc.address.toLowerCase() === embeddedAccount.address.toLowerCase());
297
+ const wallet = {
298
+ address: embeddedAccount.address,
299
+ chainType: ChainTypeEnum.SVM,
300
+ walletIndex: walletIndex >= 0 ? walletIndex : 0,
301
+ getProvider: async () => solProvider,
302
+ };
303
+ recoverPromiseRef.current = null;
304
+ setStatus({ status: 'success' });
305
+ setActiveWalletId(embeddedAccount.id);
306
+ setActiveAccount(embeddedAccount);
307
+ onSuccess({
308
+ options: setActiveOptions,
309
+ data: {
310
+ wallet,
311
+ provider: solProvider,
312
+ },
313
+ });
314
+ if (setActiveOptions.onSuccess) {
315
+ setActiveOptions.onSuccess({ wallet, provider: solProvider });
316
+ }
317
+ if (options.onSetActiveSuccess) {
318
+ options.onSetActiveSuccess(wallet, solProvider);
319
+ }
320
+ return { wallet, provider: solProvider };
321
+ }
322
+ catch (e) {
323
+ recoverPromiseRef.current = null;
324
+ const error = e instanceof OpenfortError
325
+ ? e
326
+ : new OpenfortError('Failed to set active Solana wallet', OpenfortErrorType.WALLET_ERROR);
327
+ setStatus({ status: 'error', error });
328
+ onError({
329
+ options: setActiveOptions,
330
+ error,
331
+ });
332
+ if (setActiveOptions.onError) {
333
+ setActiveOptions.onError(error);
334
+ }
335
+ if (options.onSetActiveError) {
336
+ options.onSetActiveError(error);
337
+ }
338
+ throw error;
339
+ }
340
+ })();
341
+ await recoverPromiseRef.current;
342
+ }, [client, walletConfig, embeddedAccounts, options, wallets.length, getSolanaProvider]);
343
+ // Build active wallet from embeddedWallet.get()
344
+ const activeWallet = useMemo(() => {
345
+ if (!activeWalletId || !activeAccount)
346
+ return null;
347
+ // Find the wallet index in the accounts list
348
+ const accountIndex = embeddedAccounts.findIndex((acc) => acc.id === activeWalletId);
349
+ return {
350
+ address: activeAccount.address,
351
+ chainType: ChainTypeEnum.SVM,
352
+ walletIndex: accountIndex >= 0 ? accountIndex : 0,
353
+ getProvider: async () => await getSolanaProvider(activeAccount),
354
+ };
355
+ }, [activeWalletId, activeAccount, embeddedAccounts, getSolanaProvider]);
356
+ // Build discriminated union state
357
+ const state = useMemo(() => {
358
+ const baseActions = {
359
+ create,
360
+ wallets,
361
+ setActive,
362
+ };
363
+ // Priority 1: Explicit action states (user-initiated operations)
364
+ if (status.status === 'creating') {
365
+ return { ...baseActions, status: 'creating', activeWallet: null };
366
+ }
367
+ if (status.status === 'connecting' || status.status === 'reconnecting' || status.status === 'loading') {
368
+ return { ...baseActions, status: 'connecting' };
369
+ }
370
+ if (status.status === 'error') {
371
+ return { ...baseActions, status: 'error', activeWallet, error: status.error?.message || 'Unknown error' };
372
+ }
373
+ // Priority 2: Check authentication state from context
374
+ if (embeddedState !== EmbeddedState.READY && embeddedState !== EmbeddedState.CREATING_ACCOUNT) {
375
+ // Not authenticated or no embedded wallet capability
376
+ return { ...baseActions, status: 'disconnected', activeWallet: null };
377
+ }
378
+ // Priority 3: Data-driven connection state
379
+ if (activeWallet && provider) {
380
+ // Fully connected - have both wallet and provider
381
+ return { ...baseActions, status: 'connected', activeWallet, provider };
382
+ }
383
+ if (activeAccount && !provider) {
384
+ // Have wallet but provider not initialized yet (mount recovery in progress)
385
+ return { ...baseActions, status: 'connecting' };
386
+ }
387
+ // Default: disconnected (authenticated but no wallet selected)
388
+ return { ...baseActions, status: 'disconnected', activeWallet: null };
389
+ }, [status, activeWallet, activeAccount, provider, wallets, embeddedState, create, setActive]);
390
+ return state;
391
+ }
@@ -0,0 +1,75 @@
1
+ import { RecoveryMethod } from '@openfort/openfort-js';
2
+ import { OpenfortError, OpenfortErrorType } from '../../types/openfortError';
3
+ /**
4
+ * Resolves an encryption session from wallet configuration.
5
+ *
6
+ * This utility handles encryption session resolution for automatic wallet recovery.
7
+ * It supports both callback-based session retrieval and endpoint-based session creation.
8
+ *
9
+ * @param walletConfig - The embedded wallet configuration from the provider
10
+ * @returns A promise that resolves to the encryption session string
11
+ * @throws {OpenfortError} When wallet config is missing or session cannot be retrieved
12
+ *
13
+ * @internal
14
+ */
15
+ async function resolveEncryptionSession(walletConfig) {
16
+ if (!walletConfig) {
17
+ throw new OpenfortError('Encryption session configuration is required', OpenfortErrorType.WALLET_ERROR);
18
+ }
19
+ // Try callback-based session retrieval first
20
+ if (walletConfig.getEncryptionSession) {
21
+ return await walletConfig.getEncryptionSession();
22
+ }
23
+ // Try endpoint-based session creation
24
+ if (walletConfig.createEncryptedSessionEndpoint) {
25
+ try {
26
+ const response = await fetch(walletConfig.createEncryptedSessionEndpoint, {
27
+ method: 'POST',
28
+ headers: {
29
+ 'Content-Type': 'application/json',
30
+ },
31
+ });
32
+ if (!response.ok) {
33
+ throw new OpenfortError('Failed to create encryption session', OpenfortErrorType.WALLET_ERROR, {
34
+ status: response.status,
35
+ });
36
+ }
37
+ const body = (await response.json());
38
+ if (!body?.session || typeof body.session !== 'string') {
39
+ throw new OpenfortError('Encryption session response is missing the `session` property', OpenfortErrorType.WALLET_ERROR);
40
+ }
41
+ return body.session;
42
+ }
43
+ catch (error) {
44
+ if (error instanceof OpenfortError) {
45
+ throw error;
46
+ }
47
+ throw new OpenfortError('Failed to create encryption session', OpenfortErrorType.WALLET_ERROR, { error });
48
+ }
49
+ }
50
+ throw new OpenfortError('Encryption session configuration is required', OpenfortErrorType.WALLET_ERROR);
51
+ }
52
+ /**
53
+ * Builds recovery parameters from options and wallet configuration.
54
+ *
55
+ * This utility constructs the appropriate RecoveryParams object based on whether
56
+ * a recovery password is provided or automatic recovery should be used.
57
+ *
58
+ * @param options - Options containing optional recovery password
59
+ * @param walletConfig - The embedded wallet configuration from the provider
60
+ * @returns A promise that resolves to RecoveryParams for the SDK
61
+ *
62
+ * @internal
63
+ */
64
+ export async function buildRecoveryParams(options, walletConfig) {
65
+ if (options?.recoveryPassword) {
66
+ return {
67
+ recoveryMethod: RecoveryMethod.PASSWORD,
68
+ password: options.recoveryPassword,
69
+ };
70
+ }
71
+ return {
72
+ recoveryMethod: RecoveryMethod.AUTOMATIC,
73
+ encryptionSession: await resolveEncryptionSession(walletConfig),
74
+ };
75
+ }
@@ -5,6 +5,9 @@
5
5
  * ensuring consistent callback execution across all hooks in the SDK.
6
6
  *
7
7
  * @param params - Object containing hook options and success data
8
+ * @param params.hookOptions - Primary hook options (from the hook itself)
9
+ * @param params.options - Secondary hook options (from the action call)
10
+ * @param params.data - The success data to pass to callbacks
8
11
  * @returns The success data that was passed in
9
12
  *
10
13
  * @example
@@ -29,6 +32,9 @@ export const onSuccess = ({ hookOptions, options, data, }) => {
29
32
  * and optionally throws the error if throwOnError is configured.
30
33
  *
31
34
  * @param params - Object containing hook options and error information
35
+ * @param params.hookOptions - Primary hook options (from the hook itself)
36
+ * @param params.options - Secondary hook options (from the action call)
37
+ * @param params.error - The error that occurred during the operation
32
38
  * @returns Object containing the error, or throws if throwOnError is enabled
33
39
  *
34
40
  * @example
@@ -6,6 +6,11 @@ import { Platform } from 'react-native';
6
6
  import { logger } from '../lib/logger';
7
7
  /**
8
8
  * Opens an OAuth authentication session
9
+ *
10
+ * @param config - OAuth session configuration
11
+ * @param config.url - OAuth provider URL to open
12
+ * @param config.redirectUri - Redirect URI for OAuth flow callback
13
+ * @returns Promise resolving to OAuth result indicating success, cancellation, or error
9
14
  */
10
15
  export async function openOAuthSession(config) {
11
16
  try {
@@ -38,6 +43,12 @@ export async function openOAuthSession(config) {
38
43
  }
39
44
  /**
40
45
  * Handles Apple Sign-In authentication for iOS
46
+ *
47
+ * @param options - Options for Apple authentication
48
+ * @param options.state - State parameter for the OAuth flow
49
+ * @param options.isLogin - Whether this is a login or link operation (affects error codes)
50
+ * @returns Promise resolving to Apple authentication result with authorization code and user info
51
+ * @throws {Error} When not running on iOS platform or authentication fails
41
52
  */
42
53
  export async function authenticateWithApple(options) {
43
54
  if (Platform.OS !== 'ios') {
@@ -77,6 +88,8 @@ export async function authenticateWithApple(options) {
77
88
  }
78
89
  /**
79
90
  * Checks if Apple Sign-In is available on the current device
91
+ *
92
+ * @returns Promise resolving to true if Apple Sign-In is available, false otherwise
80
93
  */
81
94
  export async function isAppleSignInAvailable() {
82
95
  if (Platform.OS !== 'ios') {
@@ -160,12 +160,16 @@ function normalizeKey(key) {
160
160
  export const NativeStorageUtils = {
161
161
  /**
162
162
  * Checks if secure storage is available on the current platform.
163
+ *
164
+ * @returns True if the platform is iOS or Android, false otherwise
163
165
  */
164
166
  isAvailable() {
165
167
  return Platform.OS === 'ios' || Platform.OS === 'android';
166
168
  },
167
169
  /**
168
170
  * Gets the platform-specific storage options.
171
+ *
172
+ * @returns Secure store options with keychain accessibility configuration
169
173
  */
170
174
  getStorageOptions() {
171
175
  return {
@@ -9,6 +9,8 @@ import { handleSecureStorageMessage, isSecureStorageMessage } from './storage';
9
9
  * WebView component for embedded wallet integration
10
10
  * Handles secure communication between React Native and the embedded wallet WebView
11
11
  * This component is hidden and only used for wallet communication
12
+ *
13
+ * @param props - Component props, see {@link EmbeddedWalletWebViewProps}
12
14
  */
13
15
  export const EmbeddedWalletWebView = ({ client, isClientReady, onProxyStatusChange, }) => {
14
16
  const webViewRef = useRef(null);
@@ -42,7 +44,7 @@ export const EmbeddedWalletWebView = ({ client, isClientReady, onProxyStatusChan
42
44
  // Set up WebView reference with client immediately when both are available
43
45
  useEffect(() => {
44
46
  if (webViewRef.current) {
45
- // Simple message poster that uses WebView's postMessage directly
47
+ // Message poster with Uint8Array preprocessing for React Native
46
48
  const messagePoster = {
47
49
  postMessage: (message) => {
48
50
  webViewRef.current?.postMessage(message);
@@ -97,12 +99,16 @@ export const EmbeddedWalletWebView = ({ client, isClientReady, onProxyStatusChan
97
99
  export const WebViewUtils = {
98
100
  /**
99
101
  * Checks if WebView is supported on the current platform
102
+ *
103
+ * @returns True if the platform is iOS or Android, false otherwise
100
104
  */
101
105
  isSupported() {
102
106
  return Platform.OS === 'ios' || Platform.OS === 'android';
103
107
  },
104
108
  /**
105
109
  * Gets platform-specific WebView configuration
110
+ *
111
+ * @returns Platform-specific WebView configuration object
106
112
  */
107
113
  getPlatformConfig() {
108
114
  if (Platform.OS === 'ios') {
@@ -123,6 +129,9 @@ export const WebViewUtils = {
123
129
  },
124
130
  /**
125
131
  * Creates a secure message for WebView communication
132
+ *
133
+ * @param data - Data to include in the message
134
+ * @returns JSON-stringified message with timestamp and platform information
126
135
  */
127
136
  createSecureMessage(data) {
128
137
  return JSON.stringify({
@@ -133,6 +142,9 @@ export const WebViewUtils = {
133
142
  },
134
143
  /**
135
144
  * Validates a message received from WebView
145
+ *
146
+ * @param message - JSON string message to validate
147
+ * @returns Validation result with parsed data or error information
136
148
  */
137
149
  validateMessage(message) {
138
150
  try {
@@ -152,6 +164,8 @@ export const WebViewUtils = {
152
164
  },
153
165
  /**
154
166
  * Gets WebView user agent for the current platform
167
+ *
168
+ * @returns User agent string including platform and version information
155
169
  */
156
170
  getUserAgent() {
157
171
  const baseAgent = 'OpenfortEmbeddedWallet/1.0';
@@ -31,6 +31,7 @@ export interface AuthBoundaryProps {
31
31
  * 3. **Unauthenticated** – the user is not logged in.
32
32
  * 4. **Authenticated** – the user is logged in and the SDK is ready.
33
33
  *
34
+ * @param props - Component props, see {@link AuthBoundaryProps}
34
35
  * @example
35
36
  * ```tsx
36
37
  * import { AuthBoundary } from '@openfort/react-native';
@@ -1,6 +1,6 @@
1
1
  export type { SDKOverrides } from '@openfort/openfort-js';
2
2
  export { RecoveryMethod } from '@openfort/openfort-js';
3
- export { createOpenfortClient, getDefaultClient, setDefaultClient } from './client';
3
+ export { createOpenfortClient } from './client';
4
4
  export type { OpenfortContextValue } from './context';
5
5
  export { isOpenfortContextValue, OpenfortContext, useOpenfortContext, useOpenfortContextSafe } from './context';
6
6
  export type { CommonEmbeddedWalletConfiguration, EmbeddedWalletConfiguration, EncryptionSession, OpenfortProviderProps, } from './provider';
@@ -1,7 +1,6 @@
1
1
  import type { AuthPlayerResponse as OpenfortUser } from '@openfort/openfort-js';
2
2
  import type { OpenfortHookOptions } from '../../types/hookOption';
3
3
  import { OpenfortError } from '../../types/openfortError';
4
- import type { CreateWalletPostAuthOptions } from './useCreateWalletPostAuth';
5
4
  export type EmailAuthResult = {
6
5
  error?: OpenfortError;
7
6
  user?: OpenfortUser;
@@ -11,13 +10,13 @@ export type SignInEmailOptions = {
11
10
  email: string;
12
11
  password: string;
13
12
  emailVerificationRedirectTo?: string;
14
- } & OpenfortHookOptions<EmailAuthResult> & CreateWalletPostAuthOptions;
13
+ } & OpenfortHookOptions<EmailAuthResult>;
15
14
  export type SignUpEmailOptions = {
16
15
  email: string;
17
16
  password: string;
18
17
  name?: string;
19
18
  emailVerificationRedirectTo?: string;
20
- } & OpenfortHookOptions<EmailAuthResult> & CreateWalletPostAuthOptions;
19
+ } & OpenfortHookOptions<EmailAuthResult>;
21
20
  export type RequestResetPasswordOptions = {
22
21
  email: string;
23
22
  emailVerificationRedirectTo?: string;
@@ -42,7 +41,7 @@ export type EmailVerificationResult = {
42
41
  };
43
42
  export type UseEmailHookOptions = {
44
43
  emailVerificationRedirectTo?: string;
45
- } & OpenfortHookOptions<EmailAuthResult | EmailVerificationResult> & CreateWalletPostAuthOptions;
44
+ } & OpenfortHookOptions<EmailAuthResult | EmailVerificationResult>;
46
45
  /**
47
46
  * Hook for email and password authentication.
48
47
  *
@@ -77,9 +76,9 @@ export declare const useEmailAuth: (hookOptions?: UseEmailHookOptions) => {
77
76
  error: Error | null;
78
77
  signInEmail: (options: SignInEmailOptions) => Promise<EmailAuthResult>;
79
78
  signUpEmail: (options: SignUpEmailOptions) => Promise<EmailAuthResult>;
80
- verifyEmail: () => void;
79
+ verifyEmail: (options: VerifyEmailOptions) => Promise<EmailVerificationResult>;
81
80
  linkEmail: (options: LinkEmailOptions) => Promise<EmailAuthResult>;
82
- requestResetPassword: () => void;
83
- resetPassword: () => void;
81
+ requestResetPassword: (options: RequestResetPasswordOptions) => Promise<EmailAuthResult>;
82
+ resetPassword: (options: ResetPasswordOptions) => Promise<EmailAuthResult>;
84
83
  reset: () => void;
85
84
  };
@@ -1,12 +1,11 @@
1
1
  import type { AuthPlayerResponse as OpenfortUser } from '@openfort/openfort-js';
2
2
  import type { OpenfortHookOptions } from '../../types/hookOption';
3
3
  import { OpenfortError } from '../../types/openfortError';
4
- import type { CreateWalletPostAuthOptions } from './useCreateWalletPostAuth';
5
4
  export type GuestHookResult = {
6
5
  error?: OpenfortError;
7
6
  user?: OpenfortUser;
8
7
  };
9
- export type GuestHookOptions = OpenfortHookOptions<GuestHookResult> & CreateWalletPostAuthOptions;
8
+ export type GuestHookOptions = OpenfortHookOptions<GuestHookResult>;
10
9
  /**
11
10
  * Hook for creating guest accounts.
12
11
  *