@openfort/react-native 0.0.3 → 0.1.1

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 (87) hide show
  1. package/README.md +0 -85
  2. package/dist/components/AuthBoundary.js +83 -0
  3. package/dist/components/index.js +10 -0
  4. package/dist/constants/config.js +9 -0
  5. package/dist/constants/index.js +1 -0
  6. package/dist/core/client.js +78 -0
  7. package/dist/core/context.js +37 -0
  8. package/dist/core/index.js +10 -0
  9. package/dist/core/provider.js +224 -0
  10. package/dist/core/storage.js +141 -0
  11. package/dist/hooks/auth/index.js +14 -0
  12. package/dist/hooks/auth/useAuthCallback.js +1 -0
  13. package/dist/hooks/auth/useCreateWalletPostAuth.js +22 -0
  14. package/dist/hooks/auth/useEmailAuth.js +176 -0
  15. package/dist/hooks/auth/useGuestAuth.js +52 -0
  16. package/dist/hooks/auth/useOAuth.js +292 -0
  17. package/dist/hooks/auth/useSignOut.js +48 -0
  18. package/dist/hooks/auth/useWalletAuth.js +133 -0
  19. package/dist/hooks/core/index.js +9 -0
  20. package/dist/hooks/core/useOpenfort.js +50 -0
  21. package/dist/hooks/core/useOpenfortClient.js +29 -0
  22. package/dist/hooks/core/useUser.js +10 -0
  23. package/dist/hooks/index.js +15 -0
  24. package/dist/hooks/wallet/index.js +7 -0
  25. package/dist/hooks/wallet/useWallets.js +389 -0
  26. package/dist/index.js +24 -1
  27. package/dist/lib/hookConsistency.js +16 -0
  28. package/dist/native/index.js +6 -0
  29. package/dist/native/oauth.js +183 -0
  30. package/dist/native/storage.js +178 -0
  31. package/dist/native/webview.js +157 -0
  32. package/dist/types/auth.js +1 -0
  33. package/dist/types/baseFlowState.js +8 -0
  34. package/dist/types/components/AuthBoundary.d.ts +85 -0
  35. package/dist/types/components/index.d.ts +10 -0
  36. package/dist/types/config.js +1 -0
  37. package/dist/types/constants/config.d.ts +9 -0
  38. package/dist/types/constants/index.d.ts +1 -0
  39. package/dist/types/core/client.d.ts +24 -0
  40. package/dist/types/core/context.d.ts +61 -0
  41. package/dist/types/core/index.d.ts +8 -0
  42. package/dist/types/core/provider.d.ts +126 -0
  43. package/dist/types/core/storage.d.ts +34 -0
  44. package/dist/types/hex.js +1 -0
  45. package/dist/types/hookOption.js +1 -0
  46. package/dist/types/hooks/auth/index.d.ts +10 -0
  47. package/dist/types/hooks/auth/useAuthCallback.d.ts +0 -0
  48. package/dist/types/hooks/auth/useCreateWalletPostAuth.d.ts +6 -0
  49. package/dist/types/hooks/auth/useEmailAuth.d.ts +59 -0
  50. package/dist/types/hooks/auth/useGuestAuth.d.ts +39 -0
  51. package/dist/types/hooks/auth/useOAuth.d.ts +62 -0
  52. package/dist/types/hooks/auth/useSignOut.d.ts +9 -0
  53. package/dist/types/hooks/auth/useWalletAuth.d.ts +48 -0
  54. package/dist/types/hooks/core/index.d.ts +8 -0
  55. package/dist/types/hooks/core/useOpenfort.d.ts +38 -0
  56. package/dist/types/hooks/core/useOpenfortClient.d.ts +29 -0
  57. package/dist/types/hooks/core/useUser.d.ts +5 -0
  58. package/dist/types/hooks/index.d.ts +12 -0
  59. package/dist/types/hooks/wallet/index.d.ts +6 -0
  60. package/dist/types/hooks/wallet/useWallets.d.ts +74 -0
  61. package/dist/types/index.d.ts +18 -1
  62. package/dist/types/index.js +2 -0
  63. package/dist/types/lib/hookConsistency.d.ts +14 -0
  64. package/dist/types/native/index.d.ts +5 -0
  65. package/dist/types/native/oauth.d.ts +91 -0
  66. package/dist/types/native/storage.d.ts +50 -0
  67. package/dist/types/native/webview.d.ts +50 -0
  68. package/dist/types/oauth.js +8 -0
  69. package/dist/types/openfortError.js +27 -0
  70. package/dist/types/predicates.js +101 -0
  71. package/dist/types/state.js +1 -0
  72. package/dist/types/types/auth.d.ts +168 -0
  73. package/dist/types/types/baseFlowState.d.ts +14 -0
  74. package/dist/types/types/config.d.ts +71 -0
  75. package/dist/types/types/hex.d.ts +1 -0
  76. package/dist/types/types/hookOption.d.ts +9 -0
  77. package/dist/types/types/index.d.ts +38 -0
  78. package/dist/types/types/oauth.d.ts +74 -0
  79. package/dist/types/types/openfortError.d.ts +13 -0
  80. package/dist/types/types/predicates.d.ts +64 -0
  81. package/dist/types/types/state.d.ts +0 -0
  82. package/dist/types/types/wallet.d.ts +262 -0
  83. package/dist/types/wallet.js +1 -0
  84. package/package.json +33 -19
  85. package/dist/Iframe.js +0 -84
  86. package/dist/types/Iframe.d.ts +0 -6
  87. package/polyfills/index.ts +0 -89
@@ -0,0 +1,133 @@
1
+ import { useCallback } from 'react';
2
+ import { useOpenfortContext } from '../../core/context';
3
+ import { onError, onSuccess } from '../../lib/hookConsistency';
4
+ import { OpenfortError, OpenfortErrorType } from '../../types/openfortError';
5
+ const mapStatus = (status) => {
6
+ return {
7
+ isLoading: status.status === 'generating-message' || status.status === 'awaiting-signature' || status.status === 'submitting-signature',
8
+ isError: status.status === 'error',
9
+ isSuccess: status.status === 'done',
10
+ error: "error" in status ? status.error : null,
11
+ isAwaitingSignature: status.status === 'awaiting-signature',
12
+ isGeneratingMessage: status.status === 'generating-message',
13
+ isSubmittingSignature: status.status === 'submitting-signature',
14
+ };
15
+ };
16
+ export function useWalletAuth(hookOptions) {
17
+ const { client, siweState, setSiweState, _internal } = useOpenfortContext();
18
+ const generateSiweMessage = useCallback(async (args) => {
19
+ try {
20
+ setSiweState({ status: 'generating-message' });
21
+ // Get wallet address from the external wallet
22
+ const walletAddress = typeof args.wallet === 'string' ? args.wallet : args.wallet.address;
23
+ const result = await client.auth.initSIWE({
24
+ address: walletAddress,
25
+ });
26
+ // Build the SIWE message
27
+ const siweMessage = `${args.from.domain} wants you to sign in with your Ethereum account:\n${walletAddress}\n\nSign in to ${args.from.domain}\n\nURI: ${args.from.uri}\nVersion: 1\nChain ID: 1\nNonce: ${result.nonce}\nIssued At: ${new Date().toISOString()}`;
28
+ setSiweState({
29
+ status: 'awaiting-signature',
30
+ });
31
+ return onSuccess({
32
+ hookOptions,
33
+ options: args,
34
+ data: { message: siweMessage },
35
+ });
36
+ }
37
+ catch (error) {
38
+ const errorObj = error instanceof Error ? error : new Error('Failed to generate SIWE message');
39
+ setSiweState({
40
+ status: 'error',
41
+ error: errorObj
42
+ });
43
+ return onError({
44
+ hookOptions,
45
+ options: args,
46
+ error: new OpenfortError('Failed to generate SIWE message', OpenfortErrorType.AUTHENTICATION_ERROR, { error: errorObj }),
47
+ });
48
+ }
49
+ }, [client, setSiweState]);
50
+ const linkSiwe = useCallback(async (opts) => {
51
+ try {
52
+ setSiweState({ status: 'submitting-signature' });
53
+ const message = opts.messageOverride || '';
54
+ if (!message) {
55
+ throw new Error('SIWE message is required. Call generateSiweMessage first.');
56
+ }
57
+ // Get current user access token for linking
58
+ const accessToken = await client.getAccessToken();
59
+ if (!accessToken) {
60
+ throw new Error('User must be authenticated to link wallet');
61
+ }
62
+ const result = await client.auth.authenticateWithSIWE({
63
+ signature: opts.signature,
64
+ message: message,
65
+ walletClientType: 'unknown',
66
+ connectorType: 'unknown',
67
+ });
68
+ setSiweState({ status: 'done' });
69
+ const user = result.player;
70
+ // Refresh user state to reflect SIWE linking
71
+ await _internal.refreshUserState();
72
+ return onSuccess({
73
+ hookOptions,
74
+ options: opts,
75
+ data: { user },
76
+ });
77
+ }
78
+ catch (e) {
79
+ const error = new OpenfortError('Failed to link in with Ethereum', OpenfortErrorType.AUTHENTICATION_ERROR, { error: e });
80
+ setSiweState({
81
+ status: 'error',
82
+ error
83
+ });
84
+ return onError({
85
+ hookOptions,
86
+ options: opts,
87
+ error
88
+ });
89
+ }
90
+ }, [client, siweState, setSiweState, _internal]);
91
+ const signInWithSiwe = useCallback(async (opts) => {
92
+ try {
93
+ setSiweState({ status: 'submitting-signature' });
94
+ const message = opts.messageOverride || '';
95
+ if (!message) {
96
+ throw new Error('SIWE message is required. Call generateSiweMessage first.');
97
+ }
98
+ const result = await client.auth.authenticateWithSIWE({
99
+ signature: opts.signature,
100
+ message: message,
101
+ walletClientType: 'unknown',
102
+ connectorType: 'unknown'
103
+ });
104
+ setSiweState({ status: 'done' });
105
+ const user = result.player;
106
+ // Refresh user state in provider
107
+ await _internal.refreshUserState(user);
108
+ return onSuccess({
109
+ hookOptions,
110
+ options: opts,
111
+ data: { user },
112
+ });
113
+ }
114
+ catch (e) {
115
+ const error = new OpenfortError('Failed to sign in with Ethereum', OpenfortErrorType.AUTHENTICATION_ERROR, { error: e });
116
+ setSiweState({
117
+ status: 'error',
118
+ error
119
+ });
120
+ return onError({
121
+ hookOptions,
122
+ options: opts,
123
+ error
124
+ });
125
+ }
126
+ }, [client, siweState, setSiweState, _internal]);
127
+ return {
128
+ generateSiweMessage,
129
+ signInWithSiwe,
130
+ linkSiwe,
131
+ ...mapStatus(siweState),
132
+ };
133
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Core hooks index
3
+ *
4
+ * This module re-exports all core SDK hooks for convenient importing.
5
+ */
6
+ // Core SDK hooks
7
+ export { useOpenfort } from './useOpenfort';
8
+ export { useOpenfortClient } from './useOpenfortClient';
9
+ export { useUser } from './useUser';
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Core Openfort hook for accessing SDK state and methods
3
+ */
4
+ import { useOpenfortContext } from '../../core/context';
5
+ /**
6
+ * Hook that exposes the core state of the Openfort SDK
7
+ *
8
+ * This hook provides access to the current authenticated user object,
9
+ * SDK initialization status, and core authentication methods.
10
+ *
11
+ * @returns The Openfort SDK's core state and methods
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * const { user, isReady, error, logout, getAccessToken } = useOpenfort();
16
+ *
17
+ * // Check if SDK is ready
18
+ * if (!isReady) {
19
+ * return <LoadingSpinner />;
20
+ * }
21
+ *
22
+ * // Handle initialization errors
23
+ * if (error) {
24
+ * return <ErrorDisplay error={error} />;
25
+ * }
26
+ *
27
+ * // Check authentication status
28
+ * if (!user) {
29
+ * return <LoginScreen />;
30
+ * }
31
+ *
32
+ * // User is authenticated
33
+ * return (
34
+ * <div>
35
+ * <h1>Welcome, {user.id}!</h1>
36
+ * <button onClick={logout}>Logout</button>
37
+ * </div>
38
+ * );
39
+ * ```
40
+ */
41
+ export function useOpenfort() {
42
+ const { user, isReady, error, logout, getAccessToken } = useOpenfortContext();
43
+ return {
44
+ user,
45
+ isReady,
46
+ error,
47
+ logout,
48
+ getAccessToken,
49
+ };
50
+ }
@@ -0,0 +1,29 @@
1
+ import { useOpenfortContext } from '../../core/context';
2
+ /**
3
+ * Hook for accessing the Openfort client instance directly
4
+ *
5
+ * This hook provides access to the underlying Openfort client for advanced use cases
6
+ * where you need direct access to the client methods.
7
+ *
8
+ * @returns The Openfort client instance
9
+ *
10
+ * @example
11
+ * ```tsx
12
+ * const client = useOpenfortClient();
13
+ *
14
+ * // Use client methods directly
15
+ * const customResult = await client.auth.customMethod();
16
+ *
17
+ * // Access client configuration
18
+ * console.log('App ID:', client.config.appId);
19
+ *
20
+ * // Check client status
21
+ * if (client.isInitialized) {
22
+ * // Perform operations that require initialization
23
+ * }
24
+ * ```
25
+ */
26
+ export function useOpenfortClient() {
27
+ const { client } = useOpenfortContext();
28
+ return client;
29
+ }
@@ -0,0 +1,10 @@
1
+ import { EmbeddedState } from "@openfort/openfort-js";
2
+ import { useOpenfortContext } from "../../core";
3
+ export function useUser() {
4
+ const { user, embeddedState, getAccessToken } = useOpenfortContext();
5
+ return {
6
+ user,
7
+ isAuthenticated: embeddedState !== EmbeddedState.NONE && embeddedState !== EmbeddedState.UNAUTHENTICATED,
8
+ getAccessToken,
9
+ };
10
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Openfort React Native SDK Hooks
3
+ *
4
+ * This module provides a comprehensive set of React hooks for integrating
5
+ * with the Openfort platform in React Native applications.
6
+ *
7
+ * The hooks are organized into the following categories:
8
+ * - Core: Core SDK functionality hooks
9
+ */
10
+ // Re-export all core hooks
11
+ export * from './core';
12
+ // Re-export all authentication hooks
13
+ export * from './auth';
14
+ // Re-export all wallet hooks
15
+ export * from './wallet';
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Wallet hooks index
3
+ *
4
+ * This module re-exports all wallet-related hooks for convenient importing.
5
+ */
6
+ // Embedded wallet hooks
7
+ export { useWallets } from './useWallets';
@@ -0,0 +1,389 @@
1
+ /**
2
+ * Hook for embedded Ethereum wallet functionality
3
+ */
4
+ import { AccountTypeEnum, ChainTypeEnum, EmbeddedState, RecoveryMethod, ShieldAuthType } from '@openfort/openfort-js';
5
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
6
+ import { useOpenfortContext } from '../../core/context';
7
+ import { onError, onSuccess } from '../../lib/hookConsistency';
8
+ import { OpenfortError, OpenfortErrorType } from '../../types/openfortError';
9
+ const mapWalletStatus = (status) => {
10
+ return {
11
+ error: status.error,
12
+ isError: status.status === 'error',
13
+ isSuccess: status.status === 'success',
14
+ isCreating: status.status === 'creating',
15
+ isConnecting: status.status === 'connecting',
16
+ };
17
+ };
18
+ /**
19
+ * Hook for interacting with embedded Ethereum wallets
20
+ *
21
+ * This hook manages embedded Ethereum wallets based on the user's state from the provider.
22
+ * Wallet state is determined by polling in the provider, not by local state management.
23
+ *
24
+ * @param props - Optional configuration with callback functions
25
+ * @returns Current embedded Ethereum wallet state with actions
26
+ *
27
+ * @example
28
+ * ```tsx
29
+ * const ethereumWallet = useEmbeddedEthereumWallet({
30
+ * onCreateWalletSuccess: (provider) => console.log('Ethereum wallet created:', provider),
31
+ * onCreateWalletError: (error) => console.error('Ethereum wallet creation failed:', error),
32
+ * });
33
+ *
34
+ * // Check wallet status and create if needed
35
+ * if (ethereumWallet.status === 'disconnected') {
36
+ * await ethereumWallet.create(); // Uses default chain
37
+ * // Or with specific chain: await ethereumWallet.create({ chainId: 1 });
38
+ * }
39
+ *
40
+ * // Use connected wallets
41
+ * if (ethereumWallet.status === 'connected' && ethereumWallet.wallets.length > 0) {
42
+ * const provider = await ethereumWallet.wallets[0].getProvider();
43
+ * // Use provider for Ethereum transactions
44
+ * }
45
+ * ```
46
+ */
47
+ export function useWallets(hookOptions = {}) {
48
+ const { client, user, supportedChains, walletConfig, embeddedState, _internal } = useOpenfortContext();
49
+ const [embeddedAccounts, setEmbeddedAccounts] = useState([]);
50
+ const recoverPromiseRef = useRef(null);
51
+ const [activeWalletId, setActiveWalletId] = useState(null); // OPENFORT-JS Should provide this
52
+ const [status, setStatus] = useState({
53
+ status: "idle",
54
+ });
55
+ const activeWallet = useMemo(() => {
56
+ if (!activeWalletId || !embeddedAccounts)
57
+ return null;
58
+ const account = embeddedAccounts.find(acc => acc.id === activeWalletId);
59
+ if (!account)
60
+ return null;
61
+ return {
62
+ address: account.address,
63
+ implementationType: account.implementationType,
64
+ ownerAddress: account.ownerAddress,
65
+ chainType: account.chainType,
66
+ isActive: true,
67
+ isConnecting: false,
68
+ getProvider: async () => {
69
+ return await client.embeddedWallet.getEthereumProvider({ announceProvider: false });
70
+ },
71
+ };
72
+ }, [activeWalletId, embeddedAccounts, client.embeddedWallet]);
73
+ const setActiveWallet = useCallback(async (options) => {
74
+ // If there's already a recovery in progress, return the existing promise
75
+ if (recoverPromiseRef.current) {
76
+ return recoverPromiseRef.current;
77
+ }
78
+ if (wallets.length === 0) {
79
+ return onError({
80
+ hookOptions,
81
+ options,
82
+ error: new OpenfortError('No embedded wallets available to set as active', OpenfortErrorType.WALLET_ERROR),
83
+ });
84
+ }
85
+ setStatus({
86
+ status: 'connecting',
87
+ address: options?.address,
88
+ });
89
+ // Create and store the recovery promise
90
+ recoverPromiseRef.current = (async () => {
91
+ try {
92
+ // Validate chainId if provided
93
+ let chainId;
94
+ if (options?.chainId) {
95
+ if (!supportedChains || !supportedChains.some(chain => chain.id === options.chainId)) {
96
+ throw new OpenfortError(`Chain ID ${options.chainId} is not supported. Supported chains: ${supportedChains?.map(c => c.id).join(', ') || 'none'}`, OpenfortErrorType.WALLET_ERROR);
97
+ }
98
+ chainId = options.chainId;
99
+ }
100
+ else if (supportedChains && supportedChains.length > 0) {
101
+ // Use the first supported chain as default
102
+ chainId = supportedChains[0].id;
103
+ }
104
+ // Create shield authentication object
105
+ let shieldAuthentication = null;
106
+ console.log('Using walletConfig:', walletConfig);
107
+ if (walletConfig) {
108
+ const accessToken = await client.getAccessToken();
109
+ if (!accessToken) {
110
+ throw new OpenfortError('Access token is required for shield authentication', OpenfortErrorType.WALLET_ERROR);
111
+ }
112
+ // Get encryption session from embedded wallet configuration
113
+ let encryptionSession;
114
+ if ('getEncryptionSession' in walletConfig && walletConfig.getEncryptionSession) {
115
+ encryptionSession = await walletConfig.getEncryptionSession();
116
+ }
117
+ shieldAuthentication = {
118
+ auth: ShieldAuthType.OPENFORT,
119
+ token: accessToken,
120
+ ...(encryptionSession && { encryptionSession }),
121
+ };
122
+ }
123
+ const address = options?.address || wallets[0]?.address;
124
+ const embeddedAccountToRecover = embeddedAccounts.find(account => account.chainId === chainId && account.address === address);
125
+ let embeddedAccount;
126
+ if (!embeddedAccountToRecover) {
127
+ // Different chain maybe?
128
+ // if (embeddedAccounts.some(account => account.address === address)) {
129
+ // create wallet with new chain
130
+ // embeddedAccount = await client.embeddedWallet.create({
131
+ // chainId: chainId!,
132
+ // accountType: AccountTypeEnum.SMART_ACCOUNT,
133
+ // chainType: ChainTypeEnum.EVM,
134
+ // shieldAuthentication: shieldAuthentication ?? undefined,
135
+ // recoveryParams: options?.recoveryPassword ? { password: options.recoveryPassword, recoveryMethod: RecoveryMethod.PASSWORD } : undefined
136
+ // });
137
+ // } else {
138
+ throw new OpenfortError(`No embedded account found for address ${address} on chain ID ${chainId}`, OpenfortErrorType.WALLET_ERROR);
139
+ // }
140
+ }
141
+ else {
142
+ // Recover the embedded wallet with shield authentication
143
+ embeddedAccount = await client.embeddedWallet.recover({
144
+ account: embeddedAccountToRecover.id,
145
+ shieldAuthentication: shieldAuthentication ?? undefined,
146
+ recoveryParams: options?.recoveryPassword ? { password: options.recoveryPassword, recoveryMethod: RecoveryMethod.PASSWORD } : undefined
147
+ });
148
+ }
149
+ const wallet = {
150
+ address: embeddedAccount.address,
151
+ implementationType: embeddedAccount.implementationType,
152
+ ownerAddress: embeddedAccount.ownerAddress,
153
+ chainType: embeddedAccount.chainType,
154
+ isActive: true,
155
+ isConnecting: false,
156
+ getProvider: async () => {
157
+ return await client.embeddedWallet.getEthereumProvider({ announceProvider: false });
158
+ },
159
+ };
160
+ recoverPromiseRef.current = null;
161
+ setStatus({
162
+ status: 'success',
163
+ });
164
+ setActiveWalletId(embeddedAccount.id);
165
+ return onSuccess({
166
+ options,
167
+ hookOptions,
168
+ data: {
169
+ wallet,
170
+ }
171
+ });
172
+ }
173
+ catch (e) {
174
+ recoverPromiseRef.current = null;
175
+ const error = e instanceof OpenfortError ? e : new OpenfortError('Failed to recover embedded wallet', OpenfortErrorType.WALLET_ERROR);
176
+ setStatus({
177
+ status: 'error',
178
+ error,
179
+ });
180
+ return onError({
181
+ options,
182
+ hookOptions,
183
+ error,
184
+ });
185
+ }
186
+ })();
187
+ return recoverPromiseRef.current;
188
+ }, [client, supportedChains, walletConfig, _internal, embeddedAccounts, hookOptions]);
189
+ // Fetch embedded wallets using embeddedWallet.list()
190
+ const fetchEmbeddedWallets = useCallback(async () => {
191
+ if (!client || embeddedState === EmbeddedState.NONE || embeddedState === EmbeddedState.UNAUTHENTICATED) {
192
+ setEmbeddedAccounts([]);
193
+ return;
194
+ }
195
+ try {
196
+ const accounts = await client.embeddedWallet.list();
197
+ setEmbeddedAccounts(accounts);
198
+ }
199
+ catch {
200
+ setEmbeddedAccounts([]);
201
+ }
202
+ }, [client, embeddedState, user]);
203
+ useEffect(() => {
204
+ fetchEmbeddedWallets();
205
+ }, [fetchEmbeddedWallets]);
206
+ useEffect(() => {
207
+ (async () => {
208
+ try {
209
+ const embeddedAccount = await client.embeddedWallet.get();
210
+ setActiveWalletId(embeddedAccount.id);
211
+ }
212
+ catch {
213
+ setActiveWalletId(null);
214
+ }
215
+ })();
216
+ }, [setActiveWalletId, client]);
217
+ // Extract Ethereum wallets from embedded accounts
218
+ const wallets = useMemo(() => (embeddedAccounts
219
+ .reduce((acc, account) => {
220
+ if (!acc.some(a => a.address === account.address)) {
221
+ acc.push(account);
222
+ }
223
+ return acc;
224
+ }, [])
225
+ .map((account) => ({
226
+ address: account.address,
227
+ implementationType: account.implementationType,
228
+ ownerAddress: account.ownerAddress,
229
+ chainType: account.chainType,
230
+ isActive: activeWalletId === account.id,
231
+ isConnecting: status.status === "connecting" && status.address === account.address,
232
+ getProvider: async () => {
233
+ return await client.embeddedWallet.getEthereumProvider({ announceProvider: false });
234
+ },
235
+ }))), [embeddedAccounts, activeWalletId, status.status === "connecting", client.embeddedWallet]);
236
+ const create = useCallback(async (options) => {
237
+ console.log('Creating Ethereum wallet with options:', options);
238
+ try {
239
+ setStatus({
240
+ status: 'creating',
241
+ });
242
+ // Validate chainId if provided
243
+ let chainId;
244
+ if (options?.chainId) {
245
+ if (!supportedChains || !supportedChains.some(chain => chain.id === options.chainId)) {
246
+ throw new OpenfortError(`Chain ID ${options.chainId} is not supported. Supported chains: ${supportedChains?.map(c => c.id).join(', ') || 'none'}`, OpenfortErrorType.WALLET_ERROR);
247
+ }
248
+ chainId = options.chainId;
249
+ }
250
+ else if (supportedChains && supportedChains.length > 0) {
251
+ // Use the first supported chain as default
252
+ chainId = supportedChains[0].id;
253
+ }
254
+ else {
255
+ throw new OpenfortError('No supported chains available for wallet creation', OpenfortErrorType.WALLET_ERROR);
256
+ }
257
+ console.log('Using chain ID for wallet creation:', chainId);
258
+ // Create shield authentication object
259
+ let shieldAuthentication = null;
260
+ if (walletConfig) {
261
+ const accessToken = await client.getAccessToken();
262
+ if (!accessToken) {
263
+ throw new Error('Access token is required for shield authentication');
264
+ }
265
+ console.log('Access token for shield authentication:', accessToken);
266
+ // Get encryption session from embedded wallet configuration
267
+ let encryptionSession;
268
+ if ('getEncryptionSession' in walletConfig && walletConfig.getEncryptionSession) {
269
+ encryptionSession = await walletConfig.getEncryptionSession();
270
+ console.log('Encryption session for shield authentication:', encryptionSession);
271
+ }
272
+ shieldAuthentication = {
273
+ auth: ShieldAuthType.OPENFORT,
274
+ token: accessToken,
275
+ ...(encryptionSession && { encryptionSession }),
276
+ };
277
+ }
278
+ console.log('Shield authentication object:', shieldAuthentication);
279
+ // Configure embedded wallet with shield authentication
280
+ const embeddedAccount = await client.embeddedWallet.create({
281
+ chainId,
282
+ accountType: AccountTypeEnum.SMART_ACCOUNT,
283
+ chainType: options?.chainType || ChainTypeEnum.EVM,
284
+ shieldAuthentication: shieldAuthentication ?? undefined,
285
+ recoveryParams: options?.recoveryPassword ? { password: options.recoveryPassword, recoveryMethod: RecoveryMethod.PASSWORD } : undefined
286
+ });
287
+ console.log('Embedded wallet configured with shield authentication');
288
+ // Get the Ethereum provider
289
+ const provider = await client.embeddedWallet.getEthereumProvider({
290
+ announceProvider: false,
291
+ ...(options?.policyId && { policy: options.policyId }),
292
+ });
293
+ // Refetch the list of wallets to ensure the state is up to date
294
+ await fetchEmbeddedWallets();
295
+ setActiveWalletId(embeddedAccount.id);
296
+ setStatus({
297
+ status: 'success',
298
+ });
299
+ return onSuccess({
300
+ hookOptions,
301
+ options,
302
+ data: {
303
+ provider,
304
+ wallet: {
305
+ address: embeddedAccount.address,
306
+ implementationType: embeddedAccount.implementationType,
307
+ ownerAddress: embeddedAccount.ownerAddress,
308
+ chainType: embeddedAccount.chainType,
309
+ isActive: true,
310
+ isConnecting: false,
311
+ getProvider: async () => {
312
+ return await client.embeddedWallet.getEthereumProvider();
313
+ },
314
+ }
315
+ }
316
+ });
317
+ }
318
+ catch (e) {
319
+ const error = e instanceof OpenfortError ? e : new OpenfortError('Failed to create Ethereum wallet', OpenfortErrorType.WALLET_ERROR, { error: e });
320
+ setStatus({
321
+ status: 'error',
322
+ error,
323
+ });
324
+ return onError({
325
+ hookOptions,
326
+ options,
327
+ error
328
+ });
329
+ }
330
+ }, [client, supportedChains, walletConfig, _internal, user]);
331
+ const setRecovery = useCallback(async (params) => {
332
+ try {
333
+ setStatus({
334
+ status: 'loading',
335
+ });
336
+ // Set embedded wallet recovery method
337
+ if (params.recoveryMethod === 'password') {
338
+ await client.embeddedWallet.setEmbeddedRecovery({
339
+ recoveryMethod: RecoveryMethod.PASSWORD,
340
+ recoveryPassword: params.recoveryPassword
341
+ });
342
+ }
343
+ else {
344
+ await client.embeddedWallet.setEmbeddedRecovery({
345
+ recoveryMethod: RecoveryMethod.AUTOMATIC
346
+ });
347
+ }
348
+ // Get the updated embedded account
349
+ const embeddedAccount = await client.embeddedWallet.get();
350
+ // Refresh user state to reflect recovery changes
351
+ await _internal.refreshUserState();
352
+ setStatus({ status: 'success' });
353
+ return onSuccess({
354
+ hookOptions,
355
+ options: params,
356
+ data: {
357
+ wallet: {
358
+ address: embeddedAccount.address,
359
+ implementationType: embeddedAccount.implementationType,
360
+ ownerAddress: embeddedAccount.ownerAddress,
361
+ chainType: embeddedAccount.chainType,
362
+ isActive: true,
363
+ isConnecting: false,
364
+ getProvider: async () => {
365
+ return await client.embeddedWallet.getEthereumProvider({ announceProvider: false });
366
+ }
367
+ }
368
+ }
369
+ });
370
+ }
371
+ catch (error) {
372
+ const errorObj = error instanceof Error ? error : new Error('Failed to set wallet recovery');
373
+ return onError({
374
+ hookOptions,
375
+ options: params,
376
+ error: new OpenfortError('Failed to set wallet recovery', OpenfortErrorType.WALLET_ERROR, { error: errorObj }),
377
+ });
378
+ }
379
+ }, [client, _internal]);
380
+ return {
381
+ wallets,
382
+ activeWallet,
383
+ setRecovery,
384
+ setActiveWallet,
385
+ createWallet: create,
386
+ ...mapWalletStatus(status),
387
+ exportPrivateKey: client.embeddedWallet.exportPrivateKey,
388
+ };
389
+ }
package/dist/index.js CHANGED
@@ -1 +1,24 @@
1
- export { default as Iframe } from './Iframe';
1
+ /**
2
+ * Openfort React Native SDK
3
+ *
4
+ * A comprehensive React Native SDK for integrating with the Openfort platform.
5
+ * This SDK provides authentication, embedded wallets, session management, and UI components
6
+ * for building decentralized applications on React Native.
7
+ *
8
+ * @author Openfort
9
+ * @version 0.1.0
10
+ */
11
+ // Re-export enums and values from @openfort/openfort-js
12
+ export { OAuthProvider, } from '@openfort/openfort-js';
13
+ // Re-export all types from the main types module
14
+ export * from './types';
15
+ // Re-export all hooks
16
+ export * from './hooks';
17
+ // Re-export all components and UI elements
18
+ export * from './components';
19
+ // Re-export core functionality
20
+ export * from './core';
21
+ // Re-export native functionality
22
+ export * from './native';
23
+ // Re-export constants
24
+ export * from './constants';