@openfort/react-native 0.1.20 → 0.1.22
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.
- package/dist/components/AuthBoundary.js +4 -1
- package/dist/core/index.js +1 -1
- package/dist/core/provider.js +20 -7
- package/dist/hooks/auth/useEmailAuth.js +108 -8
- package/dist/hooks/auth/useGuestAuth.js +16 -6
- package/dist/hooks/auth/useOAuth.js +14 -5
- package/dist/hooks/auth/useWalletAuth.js +29 -10
- package/dist/hooks/core/useOpenfort.js +3 -17
- package/dist/hooks/wallet/index.js +4 -2
- package/dist/hooks/wallet/solanaProvider.js +77 -0
- package/dist/hooks/wallet/useEmbeddedEthereumWallet.js +517 -0
- package/dist/hooks/wallet/useEmbeddedSolanaWallet.js +455 -0
- package/dist/hooks/wallet/utils.js +75 -0
- package/dist/lib/hookConsistency.js +6 -0
- package/dist/native/oauth.js +13 -0
- package/dist/native/storage.js +4 -0
- package/dist/native/webview.js +15 -1
- package/dist/types/components/AuthBoundary.d.ts +1 -0
- package/dist/types/core/index.d.ts +1 -1
- package/dist/types/core/provider.d.ts +20 -6
- package/dist/types/hooks/auth/useEmailAuth.d.ts +24 -12
- package/dist/types/hooks/auth/useGuestAuth.d.ts +17 -8
- package/dist/types/hooks/auth/useOAuth.d.ts +15 -7
- package/dist/types/hooks/auth/useWalletAuth.d.ts +29 -10
- package/dist/types/hooks/core/useOpenfort.d.ts +2 -13
- package/dist/types/hooks/wallet/index.d.ts +2 -1
- package/dist/types/hooks/wallet/solanaProvider.d.ts +75 -0
- package/dist/types/hooks/wallet/useEmbeddedEthereumWallet.d.ts +104 -0
- package/dist/types/hooks/wallet/useEmbeddedSolanaWallet.d.ts +111 -0
- package/dist/types/hooks/wallet/utils.d.ts +17 -0
- package/dist/types/index.js +1 -2
- package/dist/types/lib/hookConsistency.d.ts +6 -0
- package/dist/types/native/oauth.d.ts +13 -0
- package/dist/types/native/storage.d.ts +4 -0
- package/dist/types/native/webview.d.ts +14 -0
- package/dist/types/types/auth.d.ts +0 -41
- package/dist/types/types/index.d.ts +3 -30
- package/dist/types/types/oauth.d.ts +0 -38
- package/dist/types/types/wallet.d.ts +120 -216
- package/package.json +1 -1
- package/dist/hooks/auth/useCreateWalletPostAuth.js +0 -34
- package/dist/hooks/wallet/useWallets.js +0 -436
- package/dist/types/config.js +0 -1
- package/dist/types/hooks/auth/useCreateWalletPostAuth.d.ts +0 -1
- package/dist/types/hooks/wallet/useWallets.d.ts +0 -78
- package/dist/types/predicates.js +0 -120
- package/dist/types/types/config.d.ts +0 -39
- package/dist/types/types/predicates.d.ts +0 -118
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { useCallback } from 'react';
|
|
2
|
-
/**
|
|
3
|
-
* Hook for creating wallets after user authentication.
|
|
4
|
-
*
|
|
5
|
-
* TODO: the implementation is currently a placeholder that always returns an
|
|
6
|
-
* undefined wallet. Once the post-auth wallet flow is wired up, this helper will
|
|
7
|
-
* attempt to provision or connect an embedded wallet automatically.
|
|
8
|
-
*
|
|
9
|
-
* @returns Object containing wallet creation utilities (placeholder for now).
|
|
10
|
-
*/
|
|
11
|
-
const _useCreateWalletPostAuth = () => {
|
|
12
|
-
// This would connect to the wallet and set it as active
|
|
13
|
-
// eslint-disable-next-line no-empty-pattern
|
|
14
|
-
const tryUseWallet = useCallback(
|
|
15
|
-
// async ({/* logoutOnError: signOutOnError = true, automaticRecovery = true */}: CreateWalletPostAuthOptions) => {
|
|
16
|
-
async (_props) => {
|
|
17
|
-
// if (!walletConfig || walletConfig.recoveryMethod !== RecoveryMethod.AUTOMATIC || !automaticRecovery) {
|
|
18
|
-
// return {};
|
|
19
|
-
// }
|
|
20
|
-
// const wallet = await setActiveWallet({
|
|
21
|
-
// connector: embeddedWalletId,
|
|
22
|
-
// });
|
|
23
|
-
// if (wallet.error && signOutOnError) {
|
|
24
|
-
// // If there was an error and we should log out, we can call the logout function
|
|
25
|
-
// await signOut();
|
|
26
|
-
// }
|
|
27
|
-
return { wallet: undefined };
|
|
28
|
-
}, [
|
|
29
|
-
/* walletConfig, setActiveWallet, signOut */
|
|
30
|
-
]);
|
|
31
|
-
return {
|
|
32
|
-
tryUseWallet,
|
|
33
|
-
};
|
|
34
|
-
};
|
|
@@ -1,436 +0,0 @@
|
|
|
1
|
-
import { AccountTypeEnum, ChainTypeEnum, EmbeddedState, RecoveryMethod, } 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
|
-
const mapWalletStatus = (status) => {
|
|
8
|
-
return {
|
|
9
|
-
error: status.error,
|
|
10
|
-
isError: status.status === 'error',
|
|
11
|
-
isSuccess: status.status === 'success',
|
|
12
|
-
isCreating: status.status === 'creating',
|
|
13
|
-
isConnecting: status.status === 'connecting',
|
|
14
|
-
};
|
|
15
|
-
};
|
|
16
|
-
/**
|
|
17
|
-
* Hook for interacting with embedded wallets
|
|
18
|
-
*
|
|
19
|
-
* This hook manages embedded wallets based on the user's state from the provider. Wallet state is determined by
|
|
20
|
-
* polling in the provider, not by local state management. It provides wallet creation, recovery, and management capabilities.
|
|
21
|
-
*
|
|
22
|
-
* @param hookOptions - Optional configuration with callback functions and chain ID settings
|
|
23
|
-
* @returns Current embedded wallet state with actions and wallet collection
|
|
24
|
-
*
|
|
25
|
-
* @example
|
|
26
|
-
* ```tsx
|
|
27
|
-
* const { wallets, activeWallet, createWallet, setActiveWallet, isCreating } = useWallets({
|
|
28
|
-
* onSuccess: ({ wallet }) => console.log('Wallet operation successful:', wallet?.address),
|
|
29
|
-
* onError: ({ error }) => console.error('Wallet operation failed:', error?.message),
|
|
30
|
-
* chainId: 1, // Ethereum mainnet
|
|
31
|
-
* });
|
|
32
|
-
*
|
|
33
|
-
* // Create a new wallet if none exist
|
|
34
|
-
* if (wallets.length === 0 && !isCreating) {
|
|
35
|
-
* await createWallet({ chainId: 1 });
|
|
36
|
-
* }
|
|
37
|
-
*
|
|
38
|
-
* // Use existing wallets
|
|
39
|
-
* if (wallets.length > 0 && !activeWallet) {
|
|
40
|
-
* await setActiveWallet({ address: wallets[0].address });
|
|
41
|
-
* }
|
|
42
|
-
*
|
|
43
|
-
* // Access active wallet
|
|
44
|
-
* if (activeWallet) {
|
|
45
|
-
* const provider = await activeWallet.getProvider();
|
|
46
|
-
* // Use provider for transactions
|
|
47
|
-
* }
|
|
48
|
-
* ```
|
|
49
|
-
*/
|
|
50
|
-
export function useWallets(hookOptions = {}) {
|
|
51
|
-
const { client, user, supportedChains, walletConfig, embeddedState, _internal } = useOpenfortContext();
|
|
52
|
-
const [embeddedAccounts, setEmbeddedAccounts] = useState([]);
|
|
53
|
-
const recoverPromiseRef = useRef(null);
|
|
54
|
-
const [activeWalletId, setActiveWalletId] = useState(null);
|
|
55
|
-
const [status, setStatus] = useState({
|
|
56
|
-
status: 'idle',
|
|
57
|
-
});
|
|
58
|
-
const activeWallet = useMemo(() => {
|
|
59
|
-
if (!activeWalletId || !embeddedAccounts)
|
|
60
|
-
return null;
|
|
61
|
-
const account = embeddedAccounts.find((acc) => acc.id === activeWalletId);
|
|
62
|
-
if (!account)
|
|
63
|
-
return null;
|
|
64
|
-
return {
|
|
65
|
-
address: account.address,
|
|
66
|
-
implementationType: account.implementationType,
|
|
67
|
-
ownerAddress: account.ownerAddress,
|
|
68
|
-
chainType: account.chainType,
|
|
69
|
-
isActive: true,
|
|
70
|
-
isConnecting: false,
|
|
71
|
-
getProvider: async () => {
|
|
72
|
-
return await getEthereumProvider();
|
|
73
|
-
},
|
|
74
|
-
};
|
|
75
|
-
}, [activeWalletId, embeddedAccounts, client.embeddedWallet]);
|
|
76
|
-
const resolveEncryptionSession = useCallback(async () => {
|
|
77
|
-
if (!walletConfig) {
|
|
78
|
-
throw new OpenfortError('Encryption session configuration is required', OpenfortErrorType.WALLET_ERROR);
|
|
79
|
-
}
|
|
80
|
-
if (walletConfig.getEncryptionSession) {
|
|
81
|
-
return await walletConfig.getEncryptionSession();
|
|
82
|
-
}
|
|
83
|
-
if (walletConfig.createEncryptedSessionEndpoint) {
|
|
84
|
-
try {
|
|
85
|
-
const response = await fetch(walletConfig.createEncryptedSessionEndpoint, {
|
|
86
|
-
method: 'POST',
|
|
87
|
-
headers: {
|
|
88
|
-
'Content-Type': 'application/json',
|
|
89
|
-
},
|
|
90
|
-
});
|
|
91
|
-
if (!response.ok) {
|
|
92
|
-
throw new OpenfortError('Failed to create encryption session', OpenfortErrorType.WALLET_ERROR, {
|
|
93
|
-
status: response.status,
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
const body = (await response.json());
|
|
97
|
-
if (!body?.session || typeof body.session !== 'string') {
|
|
98
|
-
throw new OpenfortError('Encryption session response is missing the `session` property', OpenfortErrorType.WALLET_ERROR);
|
|
99
|
-
}
|
|
100
|
-
return body.session;
|
|
101
|
-
}
|
|
102
|
-
catch (error) {
|
|
103
|
-
if (error instanceof OpenfortError) {
|
|
104
|
-
throw error;
|
|
105
|
-
}
|
|
106
|
-
throw new OpenfortError('Failed to create encryption session', OpenfortErrorType.WALLET_ERROR, { error });
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
throw new OpenfortError('Encryption session configuration is required', OpenfortErrorType.WALLET_ERROR);
|
|
110
|
-
}, [walletConfig]);
|
|
111
|
-
const setActiveWallet = useCallback(async (options) => {
|
|
112
|
-
// If there's already a recovery in progress, return the existing promise
|
|
113
|
-
if (recoverPromiseRef.current) {
|
|
114
|
-
return recoverPromiseRef.current;
|
|
115
|
-
}
|
|
116
|
-
if (wallets.length === 0) {
|
|
117
|
-
return onError({
|
|
118
|
-
hookOptions,
|
|
119
|
-
options,
|
|
120
|
-
error: new OpenfortError('No embedded wallets available to set as active', OpenfortErrorType.WALLET_ERROR),
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
setStatus({
|
|
124
|
-
status: 'connecting',
|
|
125
|
-
address: options?.address,
|
|
126
|
-
});
|
|
127
|
-
// Create and store the recovery promise
|
|
128
|
-
recoverPromiseRef.current = (async () => {
|
|
129
|
-
try {
|
|
130
|
-
// Validate chainId if provided
|
|
131
|
-
let chainId;
|
|
132
|
-
if (options?.chainId) {
|
|
133
|
-
if (!supportedChains || !supportedChains.some((chain) => chain.id === options.chainId)) {
|
|
134
|
-
throw new OpenfortError(`Chain ID ${options.chainId} is not supported. Supported chains: ${supportedChains?.map((c) => c.id).join(', ') || 'none'}`, OpenfortErrorType.WALLET_ERROR);
|
|
135
|
-
}
|
|
136
|
-
chainId = options.chainId;
|
|
137
|
-
}
|
|
138
|
-
else if (supportedChains && supportedChains.length > 0) {
|
|
139
|
-
// Use the first supported chain as default
|
|
140
|
-
chainId = supportedChains[0].id;
|
|
141
|
-
}
|
|
142
|
-
const address = options?.address || wallets[0]?.address;
|
|
143
|
-
// Find account to recover based on whether we're using EOA or Smart Account
|
|
144
|
-
let embeddedAccountToRecover;
|
|
145
|
-
if (walletConfig?.accountType === AccountTypeEnum.EOA) {
|
|
146
|
-
// For EOAs, match only by address (EOAs work across all chains)
|
|
147
|
-
embeddedAccountToRecover = embeddedAccounts.find((account) => account.address.toLowerCase() === address?.toLowerCase());
|
|
148
|
-
}
|
|
149
|
-
else {
|
|
150
|
-
// For Smart Accounts, match by both address and chainId (Smart Accounts are chain-specific)
|
|
151
|
-
embeddedAccountToRecover = embeddedAccounts.find((account) => account.chainId === chainId && account.address.toLowerCase() === address?.toLowerCase());
|
|
152
|
-
}
|
|
153
|
-
let embeddedAccount;
|
|
154
|
-
if (!embeddedAccountToRecover) {
|
|
155
|
-
const errorMsg = walletConfig?.accountType === AccountTypeEnum.EOA
|
|
156
|
-
? `No embedded EOA account found for address ${address}`
|
|
157
|
-
: `No embedded smart account found for address ${address} on chain ID ${chainId}`;
|
|
158
|
-
throw new OpenfortError(errorMsg, OpenfortErrorType.WALLET_ERROR);
|
|
159
|
-
}
|
|
160
|
-
else {
|
|
161
|
-
let recoveryParams;
|
|
162
|
-
if (options?.recoveryPassword) {
|
|
163
|
-
recoveryParams = {
|
|
164
|
-
recoveryMethod: RecoveryMethod.PASSWORD,
|
|
165
|
-
password: options.recoveryPassword,
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
else {
|
|
169
|
-
recoveryParams = {
|
|
170
|
-
recoveryMethod: RecoveryMethod.AUTOMATIC,
|
|
171
|
-
encryptionSession: await resolveEncryptionSession(),
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
// Recover the embedded wallet with shield authentication
|
|
175
|
-
embeddedAccount = await client.embeddedWallet.recover({
|
|
176
|
-
account: embeddedAccountToRecover.id,
|
|
177
|
-
recoveryParams,
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
const wallet = {
|
|
181
|
-
address: embeddedAccount.address,
|
|
182
|
-
implementationType: embeddedAccount.implementationType,
|
|
183
|
-
ownerAddress: embeddedAccount.ownerAddress,
|
|
184
|
-
chainType: embeddedAccount.chainType,
|
|
185
|
-
isActive: true,
|
|
186
|
-
isConnecting: false,
|
|
187
|
-
getProvider: async () => {
|
|
188
|
-
return await getEthereumProvider();
|
|
189
|
-
},
|
|
190
|
-
};
|
|
191
|
-
recoverPromiseRef.current = null;
|
|
192
|
-
setStatus({
|
|
193
|
-
status: 'success',
|
|
194
|
-
});
|
|
195
|
-
setActiveWalletId(embeddedAccount.id);
|
|
196
|
-
return onSuccess({
|
|
197
|
-
options,
|
|
198
|
-
hookOptions,
|
|
199
|
-
data: {
|
|
200
|
-
wallet,
|
|
201
|
-
},
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
catch (e) {
|
|
205
|
-
recoverPromiseRef.current = null;
|
|
206
|
-
const error = e instanceof OpenfortError
|
|
207
|
-
? e
|
|
208
|
-
: new OpenfortError('Failed to recover embedded wallet', OpenfortErrorType.WALLET_ERROR);
|
|
209
|
-
setStatus({
|
|
210
|
-
status: 'error',
|
|
211
|
-
error,
|
|
212
|
-
});
|
|
213
|
-
return onError({
|
|
214
|
-
options,
|
|
215
|
-
hookOptions,
|
|
216
|
-
error,
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
})();
|
|
220
|
-
return recoverPromiseRef.current;
|
|
221
|
-
}, [client, supportedChains, resolveEncryptionSession, _internal, embeddedAccounts, hookOptions]);
|
|
222
|
-
// Fetch embedded wallets using embeddedWallet.list()
|
|
223
|
-
const fetchEmbeddedWallets = useCallback(async () => {
|
|
224
|
-
if (!client || embeddedState === EmbeddedState.NONE || embeddedState === EmbeddedState.UNAUTHENTICATED) {
|
|
225
|
-
setEmbeddedAccounts([]);
|
|
226
|
-
return;
|
|
227
|
-
}
|
|
228
|
-
try {
|
|
229
|
-
const accounts = await client.embeddedWallet.list({
|
|
230
|
-
limit: 100,
|
|
231
|
-
// If its EOA we want all accounts, otherwise we want only smart accounts
|
|
232
|
-
accountType: walletConfig?.accountType === AccountTypeEnum.EOA ? undefined : AccountTypeEnum.SMART_ACCOUNT,
|
|
233
|
-
});
|
|
234
|
-
setEmbeddedAccounts(accounts);
|
|
235
|
-
}
|
|
236
|
-
catch {
|
|
237
|
-
setEmbeddedAccounts([]);
|
|
238
|
-
}
|
|
239
|
-
}, [client, embeddedState, user, walletConfig]);
|
|
240
|
-
useEffect(() => {
|
|
241
|
-
fetchEmbeddedWallets();
|
|
242
|
-
}, [fetchEmbeddedWallets]);
|
|
243
|
-
const getEthereumProvider = useCallback(async () => {
|
|
244
|
-
const resolvePolicy = () => {
|
|
245
|
-
const ethereumProviderPolicyId = walletConfig?.ethereumProviderPolicyId;
|
|
246
|
-
if (!ethereumProviderPolicyId)
|
|
247
|
-
return undefined;
|
|
248
|
-
if (typeof ethereumProviderPolicyId === 'string') {
|
|
249
|
-
return ethereumProviderPolicyId;
|
|
250
|
-
}
|
|
251
|
-
if (!hookOptions.chainId)
|
|
252
|
-
return undefined;
|
|
253
|
-
const policy = ethereumProviderPolicyId[hookOptions.chainId];
|
|
254
|
-
if (!policy) {
|
|
255
|
-
return undefined;
|
|
256
|
-
}
|
|
257
|
-
return policy;
|
|
258
|
-
};
|
|
259
|
-
return await client.embeddedWallet.getEthereumProvider({ announceProvider: false, policy: resolvePolicy() });
|
|
260
|
-
}, [client.embeddedWallet]);
|
|
261
|
-
useEffect(() => {
|
|
262
|
-
;
|
|
263
|
-
(async () => {
|
|
264
|
-
try {
|
|
265
|
-
const embeddedAccount = await client.embeddedWallet.get();
|
|
266
|
-
setActiveWalletId(embeddedAccount.id);
|
|
267
|
-
}
|
|
268
|
-
catch {
|
|
269
|
-
setActiveWalletId(null);
|
|
270
|
-
}
|
|
271
|
-
})();
|
|
272
|
-
}, [setActiveWalletId, client]);
|
|
273
|
-
// Extract Ethereum wallets from embedded accounts
|
|
274
|
-
const wallets = useMemo(() => {
|
|
275
|
-
// Deduplicate accounts based on account type
|
|
276
|
-
const deduplicatedAccounts = embeddedAccounts.reduce((acc, account) => {
|
|
277
|
-
if (walletConfig?.accountType === AccountTypeEnum.EOA) {
|
|
278
|
-
// For EOAs, deduplicate by address only (EOAs work across all chains)
|
|
279
|
-
if (!acc.some((a) => a.address.toLowerCase() === account.address.toLowerCase())) {
|
|
280
|
-
acc.push(account);
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
else {
|
|
284
|
-
// For Smart Accounts, keep separate entries per chain (they're chain-specific)
|
|
285
|
-
// Only deduplicate exact matches (same address AND same chainId)
|
|
286
|
-
if (!acc.some((a) => a.address.toLowerCase() === account.address.toLowerCase() && a.chainId === account.chainId)) {
|
|
287
|
-
acc.push(account);
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
return acc;
|
|
291
|
-
}, []);
|
|
292
|
-
return deduplicatedAccounts.map((account) => ({
|
|
293
|
-
address: account.address,
|
|
294
|
-
implementationType: account.implementationType,
|
|
295
|
-
ownerAddress: account.ownerAddress,
|
|
296
|
-
chainType: account.chainType,
|
|
297
|
-
isActive: activeWalletId === account.id,
|
|
298
|
-
isConnecting: status.status === 'connecting' && status.address === account.address,
|
|
299
|
-
getProvider: async () => {
|
|
300
|
-
return await getEthereumProvider();
|
|
301
|
-
},
|
|
302
|
-
}));
|
|
303
|
-
}, [embeddedAccounts, activeWalletId, status.status, walletConfig?.accountType, client.embeddedWallet]);
|
|
304
|
-
const create = useCallback(async (options) => {
|
|
305
|
-
logger.info('Creating Ethereum wallet with options', options);
|
|
306
|
-
try {
|
|
307
|
-
setStatus({
|
|
308
|
-
status: 'creating',
|
|
309
|
-
});
|
|
310
|
-
// Validate chainId if provided
|
|
311
|
-
let chainId;
|
|
312
|
-
if (options?.chainId) {
|
|
313
|
-
if (!supportedChains || !supportedChains.some((chain) => chain.id === options.chainId)) {
|
|
314
|
-
throw new OpenfortError(`Chain ID ${options.chainId} is not supported. Supported chains: ${supportedChains?.map((c) => c.id).join(', ') || 'none'}`, OpenfortErrorType.WALLET_ERROR);
|
|
315
|
-
}
|
|
316
|
-
chainId = options.chainId;
|
|
317
|
-
}
|
|
318
|
-
else if (supportedChains && supportedChains.length > 0) {
|
|
319
|
-
// Use the first supported chain as default
|
|
320
|
-
chainId = supportedChains[0].id;
|
|
321
|
-
}
|
|
322
|
-
else if (options?.chainType !== ChainTypeEnum.SVM) {
|
|
323
|
-
throw new OpenfortError('No supported chains available for wallet creation', OpenfortErrorType.WALLET_ERROR);
|
|
324
|
-
}
|
|
325
|
-
let recoveryParams;
|
|
326
|
-
if (options?.recoveryPassword) {
|
|
327
|
-
recoveryParams = {
|
|
328
|
-
recoveryMethod: RecoveryMethod.PASSWORD,
|
|
329
|
-
password: options.recoveryPassword,
|
|
330
|
-
};
|
|
331
|
-
}
|
|
332
|
-
else {
|
|
333
|
-
recoveryParams = {
|
|
334
|
-
recoveryMethod: RecoveryMethod.AUTOMATIC,
|
|
335
|
-
encryptionSession: await resolveEncryptionSession(),
|
|
336
|
-
};
|
|
337
|
-
}
|
|
338
|
-
// Configure embedded wallet with shield authentication
|
|
339
|
-
const embeddedAccount = await client.embeddedWallet.create({
|
|
340
|
-
chainId,
|
|
341
|
-
accountType: options?.accountType || walletConfig?.accountType || AccountTypeEnum.SMART_ACCOUNT,
|
|
342
|
-
chainType: options?.chainType || ChainTypeEnum.EVM,
|
|
343
|
-
recoveryParams,
|
|
344
|
-
});
|
|
345
|
-
logger.info('Embedded wallet configured with shield authentication');
|
|
346
|
-
// Get the Ethereum provider
|
|
347
|
-
const provider = await getEthereumProvider();
|
|
348
|
-
// Refetch the list of wallets to ensure the state is up to date
|
|
349
|
-
await fetchEmbeddedWallets();
|
|
350
|
-
setActiveWalletId(embeddedAccount.id);
|
|
351
|
-
setStatus({
|
|
352
|
-
status: 'success',
|
|
353
|
-
});
|
|
354
|
-
return onSuccess({
|
|
355
|
-
hookOptions,
|
|
356
|
-
options,
|
|
357
|
-
data: {
|
|
358
|
-
provider,
|
|
359
|
-
wallet: {
|
|
360
|
-
address: embeddedAccount.address,
|
|
361
|
-
implementationType: embeddedAccount.implementationType,
|
|
362
|
-
ownerAddress: embeddedAccount.ownerAddress,
|
|
363
|
-
chainType: embeddedAccount.chainType,
|
|
364
|
-
isActive: true,
|
|
365
|
-
isConnecting: false,
|
|
366
|
-
getProvider: async () => {
|
|
367
|
-
return await client.embeddedWallet.getEthereumProvider();
|
|
368
|
-
},
|
|
369
|
-
},
|
|
370
|
-
},
|
|
371
|
-
});
|
|
372
|
-
}
|
|
373
|
-
catch (e) {
|
|
374
|
-
const error = e instanceof OpenfortError
|
|
375
|
-
? e
|
|
376
|
-
: new OpenfortError('Failed to create Ethereum wallet', OpenfortErrorType.WALLET_ERROR, { error: e });
|
|
377
|
-
setStatus({
|
|
378
|
-
status: 'error',
|
|
379
|
-
error,
|
|
380
|
-
});
|
|
381
|
-
return onError({
|
|
382
|
-
hookOptions,
|
|
383
|
-
options,
|
|
384
|
-
error,
|
|
385
|
-
});
|
|
386
|
-
}
|
|
387
|
-
}, [client, supportedChains, walletConfig, resolveEncryptionSession, _internal, user]);
|
|
388
|
-
const setRecovery = useCallback(async (params) => {
|
|
389
|
-
try {
|
|
390
|
-
setStatus({
|
|
391
|
-
status: 'loading',
|
|
392
|
-
});
|
|
393
|
-
// Set embedded wallet recovery method
|
|
394
|
-
await client.embeddedWallet.setRecoveryMethod(params.previousRecovery, params.newRecovery);
|
|
395
|
-
// Get the updated embedded account
|
|
396
|
-
const embeddedAccount = await client.embeddedWallet.get();
|
|
397
|
-
setStatus({ status: 'success' });
|
|
398
|
-
return onSuccess({
|
|
399
|
-
hookOptions,
|
|
400
|
-
options: params,
|
|
401
|
-
data: {
|
|
402
|
-
wallet: {
|
|
403
|
-
address: embeddedAccount.address,
|
|
404
|
-
implementationType: embeddedAccount.implementationType,
|
|
405
|
-
ownerAddress: embeddedAccount.ownerAddress,
|
|
406
|
-
chainType: embeddedAccount.chainType,
|
|
407
|
-
isActive: true,
|
|
408
|
-
isConnecting: false,
|
|
409
|
-
getProvider: async () => {
|
|
410
|
-
return await getEthereumProvider();
|
|
411
|
-
},
|
|
412
|
-
},
|
|
413
|
-
},
|
|
414
|
-
});
|
|
415
|
-
}
|
|
416
|
-
catch (error) {
|
|
417
|
-
const errorObj = error instanceof Error ? error : new Error('Failed to set wallet recovery');
|
|
418
|
-
return onError({
|
|
419
|
-
hookOptions,
|
|
420
|
-
options: params,
|
|
421
|
-
error: new OpenfortError('Failed to set wallet recovery', OpenfortErrorType.WALLET_ERROR, {
|
|
422
|
-
error: errorObj,
|
|
423
|
-
}),
|
|
424
|
-
});
|
|
425
|
-
}
|
|
426
|
-
}, [client, setStatus, hookOptions]);
|
|
427
|
-
return {
|
|
428
|
-
wallets,
|
|
429
|
-
activeWallet,
|
|
430
|
-
setRecovery,
|
|
431
|
-
setActiveWallet,
|
|
432
|
-
createWallet: create,
|
|
433
|
-
...mapWalletStatus(status),
|
|
434
|
-
exportPrivateKey: client.embeddedWallet.exportPrivateKey,
|
|
435
|
-
};
|
|
436
|
-
}
|
package/dist/types/config.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export type CreateWalletPostAuthOptions = any;
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { AccountTypeEnum, ChainTypeEnum, type Provider, type RecoveryParams } from '@openfort/openfort-js';
|
|
2
|
-
import type { Hex } from '../../types/hex';
|
|
3
|
-
import type { OpenfortHookOptions } from '../../types/hookOption';
|
|
4
|
-
import { OpenfortError } from '../../types/openfortError';
|
|
5
|
-
import type { UserWallet } from '../../types/wallet';
|
|
6
|
-
type SetActiveWalletResult = {
|
|
7
|
-
error?: OpenfortError;
|
|
8
|
-
wallet?: UserWallet;
|
|
9
|
-
provider?: Provider;
|
|
10
|
-
};
|
|
11
|
-
type SetActiveWalletOptions = {
|
|
12
|
-
address?: Hex | undefined;
|
|
13
|
-
chainId?: number;
|
|
14
|
-
recoveryPassword?: string;
|
|
15
|
-
} & OpenfortHookOptions<SetActiveWalletResult>;
|
|
16
|
-
type CreateWalletResult = SetActiveWalletResult;
|
|
17
|
-
type CreateWalletOptions = {
|
|
18
|
-
chainType?: ChainTypeEnum;
|
|
19
|
-
chainId?: number;
|
|
20
|
-
recoveryPassword?: string;
|
|
21
|
-
accountType?: AccountTypeEnum;
|
|
22
|
-
} & OpenfortHookOptions<CreateWalletResult>;
|
|
23
|
-
type RecoverEmbeddedWalletResult = SetActiveWalletResult;
|
|
24
|
-
type SetRecoveryOptions = {
|
|
25
|
-
previousRecovery: RecoveryParams;
|
|
26
|
-
newRecovery: RecoveryParams;
|
|
27
|
-
} & OpenfortHookOptions<CreateWalletResult>;
|
|
28
|
-
type WalletOptions = {
|
|
29
|
-
chainId?: number;
|
|
30
|
-
} & OpenfortHookOptions<SetActiveWalletResult | CreateWalletResult>;
|
|
31
|
-
/**
|
|
32
|
-
* Hook for interacting with embedded wallets
|
|
33
|
-
*
|
|
34
|
-
* This hook manages embedded wallets based on the user's state from the provider. Wallet state is determined by
|
|
35
|
-
* polling in the provider, not by local state management. It provides wallet creation, recovery, and management capabilities.
|
|
36
|
-
*
|
|
37
|
-
* @param hookOptions - Optional configuration with callback functions and chain ID settings
|
|
38
|
-
* @returns Current embedded wallet state with actions and wallet collection
|
|
39
|
-
*
|
|
40
|
-
* @example
|
|
41
|
-
* ```tsx
|
|
42
|
-
* const { wallets, activeWallet, createWallet, setActiveWallet, isCreating } = useWallets({
|
|
43
|
-
* onSuccess: ({ wallet }) => console.log('Wallet operation successful:', wallet?.address),
|
|
44
|
-
* onError: ({ error }) => console.error('Wallet operation failed:', error?.message),
|
|
45
|
-
* chainId: 1, // Ethereum mainnet
|
|
46
|
-
* });
|
|
47
|
-
*
|
|
48
|
-
* // Create a new wallet if none exist
|
|
49
|
-
* if (wallets.length === 0 && !isCreating) {
|
|
50
|
-
* await createWallet({ chainId: 1 });
|
|
51
|
-
* }
|
|
52
|
-
*
|
|
53
|
-
* // Use existing wallets
|
|
54
|
-
* if (wallets.length > 0 && !activeWallet) {
|
|
55
|
-
* await setActiveWallet({ address: wallets[0].address });
|
|
56
|
-
* }
|
|
57
|
-
*
|
|
58
|
-
* // Access active wallet
|
|
59
|
-
* if (activeWallet) {
|
|
60
|
-
* const provider = await activeWallet.getProvider();
|
|
61
|
-
* // Use provider for transactions
|
|
62
|
-
* }
|
|
63
|
-
* ```
|
|
64
|
-
*/
|
|
65
|
-
export declare function useWallets(hookOptions?: WalletOptions): {
|
|
66
|
-
exportPrivateKey: () => Promise<string>;
|
|
67
|
-
error: OpenfortError | null | undefined;
|
|
68
|
-
isError: boolean;
|
|
69
|
-
isSuccess: boolean;
|
|
70
|
-
isCreating: boolean;
|
|
71
|
-
isConnecting: boolean;
|
|
72
|
-
wallets: UserWallet[];
|
|
73
|
-
activeWallet: UserWallet | null;
|
|
74
|
-
setRecovery: (params: SetRecoveryOptions) => Promise<RecoverEmbeddedWalletResult>;
|
|
75
|
-
setActiveWallet: (options?: SetActiveWalletOptions) => Promise<SetActiveWalletResult>;
|
|
76
|
-
createWallet: (options?: CreateWalletOptions) => Promise<CreateWalletResult>;
|
|
77
|
-
};
|
|
78
|
-
export {};
|
package/dist/types/predicates.js
DELETED
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
export function isConnected(s) {
|
|
2
|
-
return s.status === 'connected';
|
|
3
|
-
}
|
|
4
|
-
export function isReconnecting(s) {
|
|
5
|
-
return s.status === 'reconnecting';
|
|
6
|
-
}
|
|
7
|
-
export function isConnecting(s) {
|
|
8
|
-
return s.status === 'connecting';
|
|
9
|
-
}
|
|
10
|
-
export function isDisconnected(s) {
|
|
11
|
-
return s.status === 'disconnected';
|
|
12
|
-
}
|
|
13
|
-
export function isNotCreated(s) {
|
|
14
|
-
return s.status === 'disconnected';
|
|
15
|
-
}
|
|
16
|
-
export function isCreating(s) {
|
|
17
|
-
return s.status === 'creating';
|
|
18
|
-
}
|
|
19
|
-
export function hasError(s) {
|
|
20
|
-
return s.status === 'error';
|
|
21
|
-
}
|
|
22
|
-
export function needsRecovery(s) {
|
|
23
|
-
return s.status === 'needs-recovery';
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Additional utility predicates
|
|
27
|
-
*/
|
|
28
|
-
/**
|
|
29
|
-
* Type guard to check if wallet is in a loading state
|
|
30
|
-
*
|
|
31
|
-
* This function determines whether a wallet is currently in a transitional state
|
|
32
|
-
* (connecting, creating, or reconnecting) and should show loading indicators.
|
|
33
|
-
*
|
|
34
|
-
* @param s - The embedded wallet state to check
|
|
35
|
-
* @returns True if the wallet is in any loading state, false otherwise
|
|
36
|
-
*
|
|
37
|
-
* @example
|
|
38
|
-
* ```tsx
|
|
39
|
-
* const { wallets } = useWallets();
|
|
40
|
-
* const wallet = wallets[0];
|
|
41
|
-
*
|
|
42
|
-
* if (isLoading(wallet)) {
|
|
43
|
-
* return <ActivityIndicator />; // Show spinner
|
|
44
|
-
* }
|
|
45
|
-
*
|
|
46
|
-
* // Safe to show wallet interface
|
|
47
|
-
* return <WalletInterface wallet={wallet} />;
|
|
48
|
-
* ```
|
|
49
|
-
*/
|
|
50
|
-
export function isLoading(s) {
|
|
51
|
-
return s.status === 'connecting' || s.status === 'creating' || s.status === 'reconnecting';
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Type guard to check if wallet is ready for use
|
|
55
|
-
*/
|
|
56
|
-
export function isReady(s) {
|
|
57
|
-
return s.status === 'connected';
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Type guard to check if wallet needs user action
|
|
61
|
-
*/
|
|
62
|
-
export function needsUserAction(s) {
|
|
63
|
-
return s.status === 'disconnected' || s.status === 'needs-recovery' || s.status === 'error';
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Type guard to check if wallet state is stable (not in transition)
|
|
67
|
-
*/
|
|
68
|
-
export function isStable(s) {
|
|
69
|
-
return !isLoading(s);
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Type guard to check if wallet can perform transactions
|
|
73
|
-
*/
|
|
74
|
-
export function canTransact(s) {
|
|
75
|
-
return s.status === 'connected';
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Gets a human-readable description of the wallet state
|
|
79
|
-
*/
|
|
80
|
-
export function getStateDescription(s) {
|
|
81
|
-
switch (s.status) {
|
|
82
|
-
case 'connected':
|
|
83
|
-
return 'Wallet is connected and ready to use';
|
|
84
|
-
case 'connecting':
|
|
85
|
-
return 'Connecting to wallet...';
|
|
86
|
-
case 'reconnecting':
|
|
87
|
-
return 'Reconnecting to wallet...';
|
|
88
|
-
case 'creating':
|
|
89
|
-
return 'Creating new wallet...';
|
|
90
|
-
case 'disconnected':
|
|
91
|
-
return 'Wallet is disconnected';
|
|
92
|
-
case 'needs-recovery':
|
|
93
|
-
return 'Wallet needs to be recovered';
|
|
94
|
-
case 'error':
|
|
95
|
-
return 'Wallet encountered an error';
|
|
96
|
-
default:
|
|
97
|
-
return 'Unknown wallet state';
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Gets appropriate action text for the current state
|
|
102
|
-
*/
|
|
103
|
-
export function getActionText(s) {
|
|
104
|
-
switch (s.status) {
|
|
105
|
-
case 'needs-recovery':
|
|
106
|
-
return 'Recover Wallet';
|
|
107
|
-
case 'error':
|
|
108
|
-
return 'Retry';
|
|
109
|
-
case 'disconnected':
|
|
110
|
-
return 'Create Wallet';
|
|
111
|
-
case 'connecting':
|
|
112
|
-
case 'creating':
|
|
113
|
-
case 'reconnecting':
|
|
114
|
-
return 'Please wait...';
|
|
115
|
-
case 'connected':
|
|
116
|
-
return 'Wallet Ready';
|
|
117
|
-
default:
|
|
118
|
-
return 'Unknown';
|
|
119
|
-
}
|
|
120
|
-
}
|