@spacesops/wdk-react-native-core 1.0.0-beta.40
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/README.md +551 -0
- package/dist/__mocks__/react.d.ts +40 -0
- package/dist/__mocks__/react.js +33 -0
- package/dist/__mocks__/react.js.map +1 -0
- package/dist/__mocks__/secureStorage.d.ts +26 -0
- package/dist/__mocks__/secureStorage.js +80 -0
- package/dist/__mocks__/secureStorage.js.map +1 -0
- package/dist/__tests__/hooks/useBalance.test.d.ts +6 -0
- package/dist/__tests__/hooks/useBalance.test.js +217 -0
- package/dist/__tests__/hooks/useBalance.test.js.map +1 -0
- package/dist/__tests__/hooks/useWallet.test.d.ts +6 -0
- package/dist/__tests__/hooks/useWallet.test.js +105 -0
- package/dist/__tests__/hooks/useWallet.test.js.map +1 -0
- package/dist/__tests__/hooks/useWalletManager.test.d.ts +6 -0
- package/dist/__tests__/hooks/useWalletManager.test.js +193 -0
- package/dist/__tests__/hooks/useWalletManager.test.js.map +1 -0
- package/dist/__tests__/hooks/useWdkApp.test.d.ts +6 -0
- package/dist/__tests__/hooks/useWdkApp.test.js +55 -0
- package/dist/__tests__/hooks/useWdkApp.test.js.map +1 -0
- package/dist/__tests__/hooks/useWorklet.test.d.ts +6 -0
- package/dist/__tests__/hooks/useWorklet.test.js +168 -0
- package/dist/__tests__/hooks/useWorklet.test.js.map +1 -0
- package/dist/__tests__/provider/WdkAppProvider.test.d.ts +6 -0
- package/dist/__tests__/provider/WdkAppProvider.test.js +57 -0
- package/dist/__tests__/provider/WdkAppProvider.test.js.map +1 -0
- package/dist/__tests__/services/accountService.test.d.ts +6 -0
- package/dist/__tests__/services/accountService.test.js +216 -0
- package/dist/__tests__/services/accountService.test.js.map +1 -0
- package/dist/__tests__/services/addressService.test.d.ts +6 -0
- package/dist/__tests__/services/addressService.test.js +246 -0
- package/dist/__tests__/services/addressService.test.js.map +1 -0
- package/dist/__tests__/services/balanceService.test.d.ts +6 -0
- package/dist/__tests__/services/balanceService.test.js +333 -0
- package/dist/__tests__/services/balanceService.test.js.map +1 -0
- package/dist/__tests__/services/walletSetupService.test.d.ts +6 -0
- package/dist/__tests__/services/walletSetupService.test.js +304 -0
- package/dist/__tests__/services/walletSetupService.test.js.map +1 -0
- package/dist/__tests__/services/walletSwitchingService.test.d.ts +6 -0
- package/dist/__tests__/services/walletSwitchingService.test.js +209 -0
- package/dist/__tests__/services/walletSwitchingService.test.js.map +1 -0
- package/dist/__tests__/services/workletLifecycleService.test.d.ts +6 -0
- package/dist/__tests__/services/workletLifecycleService.test.js +451 -0
- package/dist/__tests__/services/workletLifecycleService.test.js.map +1 -0
- package/dist/__tests__/setup.d.ts +7 -0
- package/dist/__tests__/setup.js +49 -0
- package/dist/__tests__/setup.js.map +1 -0
- package/dist/__tests__/storage/mmkvStorage.test.d.ts +6 -0
- package/dist/__tests__/storage/mmkvStorage.test.js +213 -0
- package/dist/__tests__/storage/mmkvStorage.test.js.map +1 -0
- package/dist/__tests__/store/walletStore.test.d.ts +4 -0
- package/dist/__tests__/store/walletStore.test.js +86 -0
- package/dist/__tests__/store/walletStore.test.js.map +1 -0
- package/dist/__tests__/store/workletStore.test.d.ts +4 -0
- package/dist/__tests__/store/workletStore.test.js +255 -0
- package/dist/__tests__/store/workletStore.test.js.map +1 -0
- package/dist/__tests__/types/hrpc.test.d.ts +4 -0
- package/dist/__tests__/types/hrpc.test.js +99 -0
- package/dist/__tests__/types/hrpc.test.js.map +1 -0
- package/dist/__tests__/utils/balanceUtils.test.d.ts +4 -0
- package/dist/__tests__/utils/balanceUtils.test.js +133 -0
- package/dist/__tests__/utils/balanceUtils.test.js.map +1 -0
- package/dist/__tests__/utils/errorHandling.test.d.ts +6 -0
- package/dist/__tests__/utils/errorHandling.test.js +119 -0
- package/dist/__tests__/utils/errorHandling.test.js.map +1 -0
- package/dist/__tests__/utils/errorUtils.test.d.ts +4 -0
- package/dist/__tests__/utils/errorUtils.test.js +133 -0
- package/dist/__tests__/utils/errorUtils.test.js.map +1 -0
- package/dist/__tests__/utils/initializationState.test.d.ts +6 -0
- package/dist/__tests__/utils/initializationState.test.js +243 -0
- package/dist/__tests__/utils/initializationState.test.js.map +1 -0
- package/dist/__tests__/utils/jsonUtils.test.d.ts +4 -0
- package/dist/__tests__/utils/jsonUtils.test.js +118 -0
- package/dist/__tests__/utils/jsonUtils.test.js.map +1 -0
- package/dist/__tests__/utils/mmkvKeyManager.test.d.ts +6 -0
- package/dist/__tests__/utils/mmkvKeyManager.test.js +158 -0
- package/dist/__tests__/utils/mmkvKeyManager.test.js.map +1 -0
- package/dist/__tests__/utils/mnemonicUtils.test.d.ts +4 -0
- package/dist/__tests__/utils/mnemonicUtils.test.js +40 -0
- package/dist/__tests__/utils/mnemonicUtils.test.js.map +1 -0
- package/dist/__tests__/utils/raceConditions.test.d.ts +6 -0
- package/dist/__tests__/utils/raceConditions.test.js +239 -0
- package/dist/__tests__/utils/raceConditions.test.js.map +1 -0
- package/dist/__tests__/utils/result.test.d.ts +4 -0
- package/dist/__tests__/utils/result.test.js +66 -0
- package/dist/__tests__/utils/result.test.js.map +1 -0
- package/dist/__tests__/utils/schemas.test.d.ts +4 -0
- package/dist/__tests__/utils/schemas.test.js +66 -0
- package/dist/__tests__/utils/schemas.test.js.map +1 -0
- package/dist/__tests__/utils/storeHelpers.test.d.ts +4 -0
- package/dist/__tests__/utils/storeHelpers.test.js +227 -0
- package/dist/__tests__/utils/storeHelpers.test.js.map +1 -0
- package/dist/__tests__/utils/typeGuards.test.d.ts +4 -0
- package/dist/__tests__/utils/typeGuards.test.js +175 -0
- package/dist/__tests__/utils/typeGuards.test.js.map +1 -0
- package/dist/__tests__/utils/validation.test.d.ts +4 -0
- package/dist/__tests__/utils/validation.test.js +126 -0
- package/dist/__tests__/utils/validation.test.js.map +1 -0
- package/dist/__tests__/utils/walletUtils.test.d.ts +4 -0
- package/dist/__tests__/utils/walletUtils.test.js +156 -0
- package/dist/__tests__/utils/walletUtils.test.js.map +1 -0
- package/dist/hooks/useBalance.d.ts +170 -0
- package/dist/hooks/useBalance.js +442 -0
- package/dist/hooks/useBalance.js.map +1 -0
- package/dist/hooks/useWallet.d.ts +43 -0
- package/dist/hooks/useWallet.js +193 -0
- package/dist/hooks/useWallet.js.map +1 -0
- package/dist/hooks/useWalletManager.d.ts +100 -0
- package/dist/hooks/useWalletManager.js +526 -0
- package/dist/hooks/useWalletManager.js.map +1 -0
- package/dist/hooks/useWdkApp.d.ts +66 -0
- package/dist/hooks/useWdkApp.js +74 -0
- package/dist/hooks/useWdkApp.js.map +1 -0
- package/dist/hooks/useWorklet.d.ts +66 -0
- package/dist/hooks/useWorklet.js +42 -0
- package/dist/hooks/useWorklet.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/provider/WdkAppProvider.d.ts +112 -0
- package/dist/provider/WdkAppProvider.js +558 -0
- package/dist/provider/WdkAppProvider.js.map +1 -0
- package/dist/services/accountService.d.ts +52 -0
- package/dist/services/accountService.js +119 -0
- package/dist/services/accountService.js.map +1 -0
- package/dist/services/addressService.d.ts +22 -0
- package/dist/services/addressService.js +110 -0
- package/dist/services/addressService.js.map +1 -0
- package/dist/services/balanceService.d.ts +114 -0
- package/dist/services/balanceService.js +208 -0
- package/dist/services/balanceService.js.map +1 -0
- package/dist/services/walletSetupService.d.ts +217 -0
- package/dist/services/walletSetupService.js +535 -0
- package/dist/services/walletSetupService.js.map +1 -0
- package/dist/services/walletSwitchingService.d.ts +48 -0
- package/dist/services/walletSwitchingService.js +143 -0
- package/dist/services/walletSwitchingService.js.map +1 -0
- package/dist/services/workletLifecycleService.d.ts +117 -0
- package/dist/services/workletLifecycleService.js +433 -0
- package/dist/services/workletLifecycleService.js.map +1 -0
- package/dist/storage/mmkvStorage.d.ts +44 -0
- package/dist/storage/mmkvStorage.js +348 -0
- package/dist/storage/mmkvStorage.js.map +1 -0
- package/dist/store/walletStore.d.ts +130 -0
- package/dist/store/walletStore.js +204 -0
- package/dist/store/walletStore.js.map +1 -0
- package/dist/store/workletStore.d.ts +121 -0
- package/dist/store/workletStore.js +256 -0
- package/dist/store/workletStore.js.map +1 -0
- package/dist/types/hrpc.d.ts +60 -0
- package/dist/types/hrpc.js +26 -0
- package/dist/types/hrpc.js.map +1 -0
- package/dist/types.d.ts +168 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/balanceUtils.d.ts +30 -0
- package/dist/utils/balanceUtils.js +86 -0
- package/dist/utils/balanceUtils.js.map +1 -0
- package/dist/utils/constants.d.ts +66 -0
- package/dist/utils/constants.js +73 -0
- package/dist/utils/constants.js.map +1 -0
- package/dist/utils/errorHandling.d.ts +47 -0
- package/dist/utils/errorHandling.js +54 -0
- package/dist/utils/errorHandling.js.map +1 -0
- package/dist/utils/errorUtils.d.ts +89 -0
- package/dist/utils/errorUtils.js +264 -0
- package/dist/utils/errorUtils.js.map +1 -0
- package/dist/utils/initializationState.d.ts +129 -0
- package/dist/utils/initializationState.js +220 -0
- package/dist/utils/initializationState.js.map +1 -0
- package/dist/utils/jsonUtils.d.ts +21 -0
- package/dist/utils/jsonUtils.js +67 -0
- package/dist/utils/jsonUtils.js.map +1 -0
- package/dist/utils/logger.d.ts +27 -0
- package/dist/utils/logger.js +50 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/mmkvKeyManager.d.ts +57 -0
- package/dist/utils/mmkvKeyManager.js +214 -0
- package/dist/utils/mmkvKeyManager.js.map +1 -0
- package/dist/utils/mnemonicUtils.d.ts +17 -0
- package/dist/utils/mnemonicUtils.js +28 -0
- package/dist/utils/mnemonicUtils.js.map +1 -0
- package/dist/utils/operationMutex.d.ts +69 -0
- package/dist/utils/operationMutex.js +150 -0
- package/dist/utils/operationMutex.js.map +1 -0
- package/dist/utils/result.d.ts +34 -0
- package/dist/utils/result.js +43 -0
- package/dist/utils/result.js.map +1 -0
- package/dist/utils/schemas.d.ts +365 -0
- package/dist/utils/schemas.js +152 -0
- package/dist/utils/schemas.js.map +1 -0
- package/dist/utils/storeHelpers.d.ts +112 -0
- package/dist/utils/storeHelpers.js +198 -0
- package/dist/utils/storeHelpers.js.map +1 -0
- package/dist/utils/typeGuards.d.ts +70 -0
- package/dist/utils/typeGuards.js +95 -0
- package/dist/utils/typeGuards.js.map +1 -0
- package/dist/utils/validation.d.ts +53 -0
- package/dist/utils/validation.js +152 -0
- package/dist/utils/validation.js.map +1 -0
- package/dist/utils/walletStateHelpers.d.ts +62 -0
- package/dist/utils/walletStateHelpers.js +81 -0
- package/dist/utils/walletStateHelpers.js.map +1 -0
- package/dist/utils/walletUtils.d.ts +38 -0
- package/dist/utils/walletUtils.js +87 -0
- package/dist/utils/walletUtils.js.map +1 -0
- package/package.json +79 -0
- package/src/__mocks__/react.ts +34 -0
- package/src/__mocks__/secureStorage.ts +87 -0
- package/src/__tests__/hooks/useBalance.test.ts +286 -0
- package/src/__tests__/hooks/useWallet.test.ts +122 -0
- package/src/__tests__/hooks/useWalletManager.test.ts +271 -0
- package/src/__tests__/hooks/useWdkApp.test.tsx +59 -0
- package/src/__tests__/hooks/useWorklet.test.ts +195 -0
- package/src/__tests__/provider/WdkAppProvider.test.tsx +67 -0
- package/src/__tests__/services/accountService.test.ts +337 -0
- package/src/__tests__/services/addressService.test.ts +312 -0
- package/src/__tests__/services/balanceService.test.ts +411 -0
- package/src/__tests__/services/walletSetupService.test.ts +463 -0
- package/src/__tests__/services/walletSwitchingService.test.ts +258 -0
- package/src/__tests__/services/workletLifecycleService.test.ts +514 -0
- package/src/__tests__/setup.ts +54 -0
- package/src/__tests__/storage/mmkvStorage.test.ts +325 -0
- package/src/__tests__/store/walletStore.test.ts +101 -0
- package/src/__tests__/store/workletStore.test.ts +329 -0
- package/src/__tests__/types/hrpc.test.ts +125 -0
- package/src/__tests__/utils/balanceUtils.test.ts +151 -0
- package/src/__tests__/utils/errorHandling.test.ts +147 -0
- package/src/__tests__/utils/errorUtils.test.ts +170 -0
- package/src/__tests__/utils/initializationState.test.ts +337 -0
- package/src/__tests__/utils/jsonUtils.test.ts +131 -0
- package/src/__tests__/utils/mmkvKeyManager.test.ts +205 -0
- package/src/__tests__/utils/mnemonicUtils.test.ts +48 -0
- package/src/__tests__/utils/raceConditions.test.ts +292 -0
- package/src/__tests__/utils/result.test.ts +73 -0
- package/src/__tests__/utils/schemas.test.ts +82 -0
- package/src/__tests__/utils/storeHelpers.test.ts +323 -0
- package/src/__tests__/utils/typeGuards.test.ts +209 -0
- package/src/__tests__/utils/validation.test.ts +152 -0
- package/src/__tests__/utils/walletUtils.test.ts +195 -0
- package/src/hooks/useBalance.ts +597 -0
- package/src/hooks/useWallet.ts +288 -0
- package/src/hooks/useWalletManager.ts +654 -0
- package/src/hooks/useWdkApp.ts +78 -0
- package/src/hooks/useWorklet.ts +109 -0
- package/src/index.ts +112 -0
- package/src/provider/WdkAppProvider.tsx +764 -0
- package/src/services/accountService.ts +134 -0
- package/src/services/addressService.ts +125 -0
- package/src/services/balanceService.ts +291 -0
- package/src/services/walletSetupService.ts +695 -0
- package/src/services/walletSwitchingService.ts +157 -0
- package/src/services/workletLifecycleService.ts +561 -0
- package/src/storage/mmkvStorage.ts +417 -0
- package/src/store/walletStore.ts +301 -0
- package/src/store/workletStore.ts +340 -0
- package/src/types/hrpc.ts +78 -0
- package/src/types.ts +188 -0
- package/src/utils/balanceUtils.ts +96 -0
- package/src/utils/constants.ts +84 -0
- package/src/utils/errorHandling.md +163 -0
- package/src/utils/errorHandling.ts +61 -0
- package/src/utils/errorUtils.ts +300 -0
- package/src/utils/initializationState.ts +242 -0
- package/src/utils/jsonUtils.ts +75 -0
- package/src/utils/logger.ts +54 -0
- package/src/utils/mmkvKeyManager.ts +256 -0
- package/src/utils/mnemonicUtils.ts +35 -0
- package/src/utils/operationMutex.ts +181 -0
- package/src/utils/result.ts +57 -0
- package/src/utils/schemas.ts +190 -0
- package/src/utils/storeHelpers.ts +236 -0
- package/src/utils/typeGuards.ts +129 -0
- package/src/utils/validation.ts +174 -0
- package/src/utils/walletStateHelpers.ts +104 -0
- package/src/utils/walletUtils.ts +107 -0
|
@@ -0,0 +1,654 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wallet Manager Hook
|
|
3
|
+
*
|
|
4
|
+
* Consolidated hook for wallet setup, initialization, and lifecycle management.
|
|
5
|
+
* This is the ONLY hook for wallet lifecycle operations.
|
|
6
|
+
*
|
|
7
|
+
* PURPOSE: Use this hook for wallet setup/auth flows (creating new wallets,
|
|
8
|
+
* loading existing wallets, checking if wallet exists, deleting wallets, getting mnemonic).
|
|
9
|
+
*
|
|
10
|
+
* When to use which hook:
|
|
11
|
+
* - **App initialization state**: Use `useWdkApp()` to check if app is ready
|
|
12
|
+
* - **Wallet lifecycle** (create, load, import, delete): Use this hook (`useWalletManager()`)
|
|
13
|
+
* - **Wallet operations** (addresses, account methods): Use `useWallet()` AFTER initialization
|
|
14
|
+
* - **Balance fetching**: Use `useBalance()` hook with TanStack Query
|
|
15
|
+
*
|
|
16
|
+
* **Wallet Switching**: Use `useWallet({ walletId })` to switch wallets.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```tsx
|
|
20
|
+
* // Check if app is ready first
|
|
21
|
+
* const { isReady } = useWdkApp()
|
|
22
|
+
*
|
|
23
|
+
* // Then use wallet manager for lifecycle operations
|
|
24
|
+
* // networkConfigs is optional - it will be retrieved from workletStore if not provided
|
|
25
|
+
* const {
|
|
26
|
+
* createWallet,
|
|
27
|
+
* initializeWallet,
|
|
28
|
+
* initializeFromMnemonic,
|
|
29
|
+
* hasWallet,
|
|
30
|
+
* deleteWallet,
|
|
31
|
+
* getMnemonic,
|
|
32
|
+
* createTemporaryWallet,
|
|
33
|
+
* isInitializing,
|
|
34
|
+
* error
|
|
35
|
+
* } = useWalletManager('user@example.com')
|
|
36
|
+
*
|
|
37
|
+
* // Create new wallet (persistent, requires biometrics)
|
|
38
|
+
* // networkConfigs can be passed here or retrieved from store
|
|
39
|
+
* await createWallet('user@example.com', networkConfigs)
|
|
40
|
+
*
|
|
41
|
+
* // Initialize wallet (create new or load existing)
|
|
42
|
+
* await initializeWallet({ createNew: true })
|
|
43
|
+
*
|
|
44
|
+
* // Load existing wallet (requires biometric authentication)
|
|
45
|
+
* await initializeWallet({ createNew: false })
|
|
46
|
+
*
|
|
47
|
+
* // Import from mnemonic
|
|
48
|
+
* await initializeFromMnemonic('word1 word2 ... word12')
|
|
49
|
+
*
|
|
50
|
+
* // Create temporary wallet for previewing addresses (no biometrics, not saved)
|
|
51
|
+
* await createTemporaryWallet()
|
|
52
|
+
*
|
|
53
|
+
* // Get mnemonic (requires biometric authentication if not cached)
|
|
54
|
+
* const mnemonic = await getMnemonic()
|
|
55
|
+
*
|
|
56
|
+
* // Delete wallet
|
|
57
|
+
* await deleteWallet()
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
|
|
61
|
+
import { useCallback, useMemo, useState } from 'react'
|
|
62
|
+
import { useShallow } from 'zustand/react/shallow'
|
|
63
|
+
|
|
64
|
+
import { WalletSetupService } from '../services/walletSetupService'
|
|
65
|
+
import { WorkletLifecycleService } from '../services/workletLifecycleService'
|
|
66
|
+
import { getWalletStore } from '../store/walletStore'
|
|
67
|
+
import { getWorkletStore } from '../store/workletStore'
|
|
68
|
+
import { updateWalletLoadingState, isWalletLoadingState, getWalletIdFromLoadingState } from '../store/walletStore'
|
|
69
|
+
import { withOperationMutex } from '../utils/operationMutex'
|
|
70
|
+
import { log, logError } from '../utils/logger'
|
|
71
|
+
import type { NetworkConfigs } from '../types'
|
|
72
|
+
import type { WalletInfo } from '../store/walletStore'
|
|
73
|
+
|
|
74
|
+
// Re-export WalletInfo for backward compatibility
|
|
75
|
+
export type { WalletInfo }
|
|
76
|
+
|
|
77
|
+
export interface UseWalletManagerResult {
|
|
78
|
+
/** Initialize wallet - either create new or load existing */
|
|
79
|
+
initializeWallet: (options?: { createNew?: boolean; walletId?: string }) => Promise<void>
|
|
80
|
+
/** Initialize wallet from mnemonic seedphrase */
|
|
81
|
+
initializeFromMnemonic: (mnemonic: string, walletId?: string) => Promise<void>
|
|
82
|
+
/** Check if wallet exists */
|
|
83
|
+
hasWallet: (walletId?: string) => Promise<boolean>
|
|
84
|
+
/** Delete wallet */
|
|
85
|
+
deleteWallet: (walletId?: string) => Promise<void>
|
|
86
|
+
/** Get mnemonic phrase (requires biometric authentication if not cached) */
|
|
87
|
+
getMnemonic: (walletId?: string) => Promise<string | null>
|
|
88
|
+
/** Create a temporary wallet for previewing addresses (no biometrics, not saved) */
|
|
89
|
+
createTemporaryWallet: () => Promise<void>
|
|
90
|
+
/** Whether initialization is in progress */
|
|
91
|
+
isInitializing: boolean
|
|
92
|
+
/** Error message if any */
|
|
93
|
+
error: string | null
|
|
94
|
+
/** Clear error state */
|
|
95
|
+
clearError: () => void
|
|
96
|
+
/** Clear active wallet ID (useful when switching users or logging out) */
|
|
97
|
+
clearActiveWallet: () => void
|
|
98
|
+
// Wallet list operations (merged from useWalletList)
|
|
99
|
+
/** List of all known wallets */
|
|
100
|
+
wallets: WalletInfo[]
|
|
101
|
+
/** Currently active wallet identifier */
|
|
102
|
+
activeWalletId: string | null
|
|
103
|
+
/** Create a new wallet with the given walletId (adds to list) */
|
|
104
|
+
createWallet: (walletId: string, networkConfigs?: NetworkConfigs) => Promise<void>
|
|
105
|
+
/** Refresh the wallet list */
|
|
106
|
+
refreshWalletList: (knownIdentifiers?: string[]) => Promise<void>
|
|
107
|
+
/** Whether wallet list operation is in progress */
|
|
108
|
+
isWalletListLoading: boolean
|
|
109
|
+
/** Wallet list error message if any */
|
|
110
|
+
walletListError: string | null
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export function useWalletManager(
|
|
114
|
+
walletId?: string,
|
|
115
|
+
networkConfigs?: NetworkConfigs
|
|
116
|
+
): UseWalletManagerResult {
|
|
117
|
+
const [error, setError] = useState<string | null>(null)
|
|
118
|
+
|
|
119
|
+
// Local loading and error state for wallet list operations (ephemeral, only used in this hook)
|
|
120
|
+
const [isWalletListLoading, setIsWalletListLoading] = useState(false)
|
|
121
|
+
const [walletListError, setWalletListError] = useState<string | null>(null)
|
|
122
|
+
|
|
123
|
+
const walletStore = getWalletStore()
|
|
124
|
+
const workletStore = getWorkletStore()
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Get networkConfigs from parameter or workletStore
|
|
128
|
+
* Throws error if not available from either source
|
|
129
|
+
*/
|
|
130
|
+
const getNetworkConfigs = useCallback((): NetworkConfigs => {
|
|
131
|
+
const networkConfigsFromStore = workletStore.getState().networkConfigs
|
|
132
|
+
const effectiveNetworkConfigs = networkConfigs ?? networkConfigsFromStore
|
|
133
|
+
|
|
134
|
+
if (!effectiveNetworkConfigs) {
|
|
135
|
+
throw new Error(
|
|
136
|
+
'networkConfigs is required. Either provide it as a parameter or ensure the worklet is started with networkConfigs.'
|
|
137
|
+
)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return effectiveNetworkConfigs
|
|
141
|
+
}, [networkConfigs])
|
|
142
|
+
// Note: workletStore removed from deps - it's a singleton that never changes
|
|
143
|
+
|
|
144
|
+
// Subscribe to wallet list state and loading state from Zustand
|
|
145
|
+
const walletListState = walletStore(
|
|
146
|
+
useShallow((state: import('../store/walletStore').WalletStore) => ({
|
|
147
|
+
wallets: state.walletList,
|
|
148
|
+
activeWalletId: state.activeWalletId,
|
|
149
|
+
walletLoadingState: state.walletLoadingState,
|
|
150
|
+
}))
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
// Derive isInitializing from walletLoadingState (single source of truth)
|
|
154
|
+
// Check if the current walletId matches the loading state identifier
|
|
155
|
+
const isInitializing = useMemo(() => {
|
|
156
|
+
const loadingState = walletListState.walletLoadingState
|
|
157
|
+
const currentWalletId = walletId || walletListState.activeWalletId
|
|
158
|
+
const loadingWalletId = getWalletIdFromLoadingState(loadingState)
|
|
159
|
+
|
|
160
|
+
// Only consider it initializing if:
|
|
161
|
+
// 1. The loading state indicates loading/checking
|
|
162
|
+
// 2. The walletId matches (or no walletId specified, meaning we're tracking active wallet)
|
|
163
|
+
return isWalletLoadingState(loadingState) &&
|
|
164
|
+
(currentWalletId === null || currentWalletId === loadingWalletId || walletId === undefined)
|
|
165
|
+
}, [walletListState.walletLoadingState, walletId, walletListState.activeWalletId])
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Initialize wallet - either create new or load existing
|
|
169
|
+
*
|
|
170
|
+
* @param options - Wallet initialization options
|
|
171
|
+
* @param options.createNew - If true, creates a new wallet; if false, loads existing wallet
|
|
172
|
+
* @param options.walletId - Optional walletId override (defaults to hook's walletId)
|
|
173
|
+
*/
|
|
174
|
+
const initializeWallet = useCallback(
|
|
175
|
+
async (options: { createNew?: boolean; walletId?: string } = {}) => {
|
|
176
|
+
setError(null)
|
|
177
|
+
const targetWalletId = options.walletId ?? walletId
|
|
178
|
+
const walletStore = getWalletStore()
|
|
179
|
+
const effectiveNetworkConfigs = getNetworkConfigs()
|
|
180
|
+
|
|
181
|
+
try {
|
|
182
|
+
// Check if wallet is already ready before attempting to initialize
|
|
183
|
+
// This prevents unnecessary initialization calls when the wallet is already loaded
|
|
184
|
+
if (targetWalletId) {
|
|
185
|
+
const currentWalletState = walletStore.getState().walletLoadingState
|
|
186
|
+
if (currentWalletState.type === 'ready' && currentWalletState.identifier === targetWalletId) {
|
|
187
|
+
log('[useWalletManager] Wallet already ready - skipping initialization', { targetWalletId })
|
|
188
|
+
return
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Update loading state in store (single source of truth)
|
|
193
|
+
if (targetWalletId) {
|
|
194
|
+
walletStore.setState((prev) => updateWalletLoadingState(prev, {
|
|
195
|
+
type: 'loading',
|
|
196
|
+
identifier: targetWalletId,
|
|
197
|
+
walletExists: true,
|
|
198
|
+
}))
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
await WalletSetupService.initializeWallet(
|
|
202
|
+
effectiveNetworkConfigs,
|
|
203
|
+
{
|
|
204
|
+
...options,
|
|
205
|
+
walletId: targetWalletId,
|
|
206
|
+
}
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
// Mark as ready on success
|
|
210
|
+
// Wallet is ready when initializeWDK() completes successfully, even if addresses don't exist yet
|
|
211
|
+
// (Addresses are lazy-loaded when getAddress() is called)
|
|
212
|
+
// This matches the pattern used in WalletSwitchingService.switchToWallet()
|
|
213
|
+
if (targetWalletId) {
|
|
214
|
+
walletStore.setState((prev) => {
|
|
215
|
+
const currentState = prev.walletLoadingState
|
|
216
|
+
const addresses = prev.addresses[targetWalletId]
|
|
217
|
+
const hasAddresses = !!(addresses && Object.keys(addresses).length > 0)
|
|
218
|
+
|
|
219
|
+
// If addresses exist, we can set to ready if state allows it
|
|
220
|
+
// WdkAppProvider will also handle transitions when addresses appear
|
|
221
|
+
if (hasAddresses) {
|
|
222
|
+
// Only set to ready if current state allows the transition
|
|
223
|
+
// Valid transitions to ready: from 'loading' or 'checking'
|
|
224
|
+
if (currentState.type === 'loading' || currentState.type === 'checking') {
|
|
225
|
+
const readyStateUpdate = updateWalletLoadingState(prev, {
|
|
226
|
+
type: 'ready',
|
|
227
|
+
identifier: targetWalletId,
|
|
228
|
+
})
|
|
229
|
+
// Also set activeWalletId to prevent WdkAppProvider from resetting state
|
|
230
|
+
return {
|
|
231
|
+
...readyStateUpdate,
|
|
232
|
+
activeWalletId: targetWalletId,
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
// If state is 'not_loaded', let WdkAppProvider handle it (it will transition when addresses exist)
|
|
236
|
+
// If state is already 'ready', don't change it
|
|
237
|
+
return prev
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// If no addresses yet, set to ready if state is 'loading' or 'checking' (normal case)
|
|
241
|
+
// The wallet is ready when WDK is initialized with correct credentials, addresses can be fetched lazily
|
|
242
|
+
// Note: Cannot transition from 'not_loaded' directly to 'ready' - must go through 'loading' first
|
|
243
|
+
if (currentState.type === 'loading' || currentState.type === 'checking') {
|
|
244
|
+
const readyStateUpdate = updateWalletLoadingState(prev, {
|
|
245
|
+
type: 'ready',
|
|
246
|
+
identifier: targetWalletId,
|
|
247
|
+
})
|
|
248
|
+
// Also set activeWalletId to prevent WdkAppProvider from resetting state
|
|
249
|
+
return {
|
|
250
|
+
...readyStateUpdate,
|
|
251
|
+
activeWalletId: targetWalletId,
|
|
252
|
+
}
|
|
253
|
+
} else if (currentState.type === 'not_loaded') {
|
|
254
|
+
// State was reset to not_loaded by WdkAppProvider
|
|
255
|
+
// We need to transition through 'loading' first, then 'ready'
|
|
256
|
+
// Since initializeWDK() already completed successfully, we can do both transitions
|
|
257
|
+
// in sequence within the same setState call
|
|
258
|
+
log('[useWalletManager] State reset to not_loaded, transitioning through loading to ready', {
|
|
259
|
+
targetWalletId,
|
|
260
|
+
hasAddresses,
|
|
261
|
+
})
|
|
262
|
+
// First transition: not_loaded -> loading
|
|
263
|
+
const loadingStateUpdate = updateWalletLoadingState(prev, {
|
|
264
|
+
type: 'loading',
|
|
265
|
+
identifier: targetWalletId,
|
|
266
|
+
walletExists: true,
|
|
267
|
+
})
|
|
268
|
+
// Second transition: loading -> ready (using the updated state)
|
|
269
|
+
const readyStateUpdate = updateWalletLoadingState(
|
|
270
|
+
{ ...prev, ...loadingStateUpdate } as typeof prev,
|
|
271
|
+
{
|
|
272
|
+
type: 'ready',
|
|
273
|
+
identifier: targetWalletId,
|
|
274
|
+
}
|
|
275
|
+
)
|
|
276
|
+
// Also set activeWalletId to prevent WdkAppProvider from resetting state
|
|
277
|
+
return {
|
|
278
|
+
...readyStateUpdate,
|
|
279
|
+
activeWalletId: targetWalletId,
|
|
280
|
+
}
|
|
281
|
+
} else {
|
|
282
|
+
// State is 'ready' or 'error' - don't change it
|
|
283
|
+
log('[useWalletManager] Wallet already in final state, not changing', {
|
|
284
|
+
currentState: currentState.type,
|
|
285
|
+
targetWalletId,
|
|
286
|
+
hasAddresses,
|
|
287
|
+
})
|
|
288
|
+
return prev
|
|
289
|
+
}
|
|
290
|
+
})
|
|
291
|
+
}
|
|
292
|
+
} catch (err) {
|
|
293
|
+
const errorMessage =
|
|
294
|
+
err instanceof Error ? err.message : String(err)
|
|
295
|
+
const errorObj = err instanceof Error ? err : new Error(String(err))
|
|
296
|
+
logError('Failed to initialize wallet:', err)
|
|
297
|
+
setError(errorMessage)
|
|
298
|
+
|
|
299
|
+
// Cleanup state on error
|
|
300
|
+
if (targetWalletId) {
|
|
301
|
+
walletStore.setState((prev) => updateWalletLoadingState(prev, {
|
|
302
|
+
type: 'error',
|
|
303
|
+
identifier: targetWalletId,
|
|
304
|
+
error: errorObj,
|
|
305
|
+
}))
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
throw err
|
|
309
|
+
}
|
|
310
|
+
},
|
|
311
|
+
[getNetworkConfigs, walletId]
|
|
312
|
+
)
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Check if wallet exists
|
|
316
|
+
*
|
|
317
|
+
* @param walletId - Optional walletId override (defaults to hook's walletId)
|
|
318
|
+
* @returns Promise resolving to true if wallet exists, false otherwise
|
|
319
|
+
*/
|
|
320
|
+
const hasWallet = useCallback(
|
|
321
|
+
async (walletIdParam?: string): Promise<boolean> => {
|
|
322
|
+
return WalletSetupService.hasWallet(walletIdParam ?? walletId)
|
|
323
|
+
},
|
|
324
|
+
[walletId]
|
|
325
|
+
)
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Initialize wallet from mnemonic seedphrase
|
|
329
|
+
*
|
|
330
|
+
* @param mnemonic - Mnemonic phrase to import
|
|
331
|
+
* @param walletId - Optional walletId override (defaults to hook's walletId)
|
|
332
|
+
*/
|
|
333
|
+
const initializeFromMnemonic = useCallback(
|
|
334
|
+
async (mnemonic: string, walletIdParam?: string) => {
|
|
335
|
+
setError(null)
|
|
336
|
+
const targetWalletId = walletIdParam ?? walletId
|
|
337
|
+
const walletStore = getWalletStore()
|
|
338
|
+
const effectiveNetworkConfigs = getNetworkConfigs()
|
|
339
|
+
|
|
340
|
+
try {
|
|
341
|
+
// Update loading state in store (single source of truth)
|
|
342
|
+
if (targetWalletId) {
|
|
343
|
+
walletStore.setState((prev) => updateWalletLoadingState(prev, {
|
|
344
|
+
type: 'loading',
|
|
345
|
+
identifier: targetWalletId,
|
|
346
|
+
walletExists: false, // New wallet from mnemonic
|
|
347
|
+
}))
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
await WalletSetupService.initializeFromMnemonic(
|
|
351
|
+
effectiveNetworkConfigs,
|
|
352
|
+
mnemonic,
|
|
353
|
+
targetWalletId
|
|
354
|
+
)
|
|
355
|
+
|
|
356
|
+
// Mark as ready on success
|
|
357
|
+
if (targetWalletId) {
|
|
358
|
+
walletStore.setState((prev) => updateWalletLoadingState(prev, {
|
|
359
|
+
type: 'ready',
|
|
360
|
+
identifier: targetWalletId,
|
|
361
|
+
}))
|
|
362
|
+
}
|
|
363
|
+
} catch (err) {
|
|
364
|
+
const errorMessage =
|
|
365
|
+
err instanceof Error ? err.message : String(err)
|
|
366
|
+
const errorObj = err instanceof Error ? err : new Error(String(err))
|
|
367
|
+
logError('Failed to initialize wallet from mnemonic:', err)
|
|
368
|
+
setError(errorMessage)
|
|
369
|
+
|
|
370
|
+
// Cleanup state on error
|
|
371
|
+
if (targetWalletId) {
|
|
372
|
+
walletStore.setState((prev) => updateWalletLoadingState(prev, {
|
|
373
|
+
type: 'error',
|
|
374
|
+
identifier: targetWalletId,
|
|
375
|
+
error: errorObj,
|
|
376
|
+
}))
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
throw err
|
|
380
|
+
}
|
|
381
|
+
},
|
|
382
|
+
[getNetworkConfigs, walletId]
|
|
383
|
+
)
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Delete wallet
|
|
387
|
+
*
|
|
388
|
+
* @param walletId - Optional walletId override (defaults to hook's walletId)
|
|
389
|
+
* If not provided, deletes the default wallet
|
|
390
|
+
*/
|
|
391
|
+
const deleteWallet = useCallback(
|
|
392
|
+
async (walletIdParam?: string) => {
|
|
393
|
+
setError(null)
|
|
394
|
+
|
|
395
|
+
try {
|
|
396
|
+
const targetWalletId = walletIdParam ?? walletId
|
|
397
|
+
if (!targetWalletId) {
|
|
398
|
+
throw new Error('Wallet ID is required for deletion')
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
await WalletSetupService.deleteWallet(targetWalletId)
|
|
402
|
+
|
|
403
|
+
// Remove from wallet list and clear all wallet-specific data
|
|
404
|
+
walletStore.setState((state: import('../store/walletStore').WalletStore) => {
|
|
405
|
+
const wasActive = state.activeWalletId === targetWalletId
|
|
406
|
+
|
|
407
|
+
// Clear all wallet-specific data (only if walletId exists)
|
|
408
|
+
const remainingAddresses = { ...state.addresses }
|
|
409
|
+
const remainingBalances = { ...state.balances }
|
|
410
|
+
const remainingAccountList = { ...state.accountList }
|
|
411
|
+
const remainingLastBalanceUpdate = { ...state.lastBalanceUpdate }
|
|
412
|
+
const remainingWalletLoading = { ...state.walletLoading }
|
|
413
|
+
const remainingBalanceLoading = { ...state.balanceLoading }
|
|
414
|
+
|
|
415
|
+
delete remainingAddresses[targetWalletId]
|
|
416
|
+
delete remainingBalances[targetWalletId]
|
|
417
|
+
delete remainingAccountList[targetWalletId]
|
|
418
|
+
delete remainingLastBalanceUpdate[targetWalletId]
|
|
419
|
+
delete remainingWalletLoading[targetWalletId]
|
|
420
|
+
delete remainingBalanceLoading[targetWalletId]
|
|
421
|
+
|
|
422
|
+
return {
|
|
423
|
+
walletList: state.walletList.filter((w: import('../store/walletStore').WalletInfo) => w.identifier !== targetWalletId),
|
|
424
|
+
activeWalletId: wasActive ? null : state.activeWalletId,
|
|
425
|
+
// Reset loading state if this was the active wallet
|
|
426
|
+
walletLoadingState: wasActive ? { type: 'not_loaded' } : state.walletLoadingState,
|
|
427
|
+
// Clear all wallet-specific data
|
|
428
|
+
addresses: remainingAddresses,
|
|
429
|
+
balances: remainingBalances,
|
|
430
|
+
accountList: remainingAccountList,
|
|
431
|
+
lastBalanceUpdate: remainingLastBalanceUpdate,
|
|
432
|
+
walletLoading: remainingWalletLoading,
|
|
433
|
+
balanceLoading: remainingBalanceLoading,
|
|
434
|
+
}
|
|
435
|
+
})
|
|
436
|
+
|
|
437
|
+
log(`[useWalletManager] Deleted wallet and cleared all data: ${targetWalletId}`)
|
|
438
|
+
} catch (err) {
|
|
439
|
+
const errorMessage =
|
|
440
|
+
err instanceof Error ? err.message : String(err)
|
|
441
|
+
logError('Failed to delete wallet:', err)
|
|
442
|
+
setError(errorMessage)
|
|
443
|
+
throw err
|
|
444
|
+
}
|
|
445
|
+
},
|
|
446
|
+
[walletId]
|
|
447
|
+
)
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* Get mnemonic phrase from wallet
|
|
451
|
+
* Requires biometric authentication if credentials are not cached
|
|
452
|
+
*
|
|
453
|
+
* @param walletId - Optional walletId override (defaults to hook's walletId)
|
|
454
|
+
* @returns Promise resolving to mnemonic phrase or null if not found
|
|
455
|
+
*/
|
|
456
|
+
const getMnemonic = useCallback(
|
|
457
|
+
async (walletIdParam?: string): Promise<string | null> => {
|
|
458
|
+
try {
|
|
459
|
+
return await WalletSetupService.getMnemonic(walletIdParam ?? walletId)
|
|
460
|
+
} catch (err) {
|
|
461
|
+
const errorMessage =
|
|
462
|
+
err instanceof Error ? err.message : String(err)
|
|
463
|
+
logError('Failed to get mnemonic:', err)
|
|
464
|
+
throw err
|
|
465
|
+
}
|
|
466
|
+
},
|
|
467
|
+
[walletId]
|
|
468
|
+
)
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* Clear error state
|
|
472
|
+
*/
|
|
473
|
+
const clearError = useCallback(() => {
|
|
474
|
+
setError(null)
|
|
475
|
+
}, [])
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Clear active wallet ID
|
|
479
|
+
* Useful when switching users or logging out to prevent auto-initialization with wrong wallet
|
|
480
|
+
*/
|
|
481
|
+
const clearActiveWallet = useCallback(() => {
|
|
482
|
+
walletStore.setState({ activeWalletId: null })
|
|
483
|
+
log('[useWalletManager] Cleared active wallet ID')
|
|
484
|
+
}, [])
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* Create a temporary wallet for previewing addresses
|
|
488
|
+
* This creates a wallet in memory only (no biometrics, not saved to secure storage)
|
|
489
|
+
* Useful for previewing addresses before committing to creating a real wallet
|
|
490
|
+
*/
|
|
491
|
+
const createTemporaryWallet = useCallback(async () => {
|
|
492
|
+
return withOperationMutex('createTemporaryWallet', async () => {
|
|
493
|
+
setError(null)
|
|
494
|
+
|
|
495
|
+
try {
|
|
496
|
+
const effectiveNetworkConfigs = getNetworkConfigs()
|
|
497
|
+
|
|
498
|
+
// Ensure worklet is started (auto-start if needed)
|
|
499
|
+
await WorkletLifecycleService.ensureWorkletStarted(
|
|
500
|
+
effectiveNetworkConfigs,
|
|
501
|
+
{ autoStart: true }
|
|
502
|
+
)
|
|
503
|
+
|
|
504
|
+
// Generate entropy and encrypt (no biometrics, no keychain save)
|
|
505
|
+
const result = await WorkletLifecycleService.generateEntropyAndEncrypt()
|
|
506
|
+
|
|
507
|
+
// Initialize WDK with temporary credentials
|
|
508
|
+
await WorkletLifecycleService.initializeWDK({
|
|
509
|
+
encryptionKey: result.encryptionKey,
|
|
510
|
+
encryptedSeed: result.encryptedSeedBuffer,
|
|
511
|
+
})
|
|
512
|
+
|
|
513
|
+
// Don't update activeWalletId for temporary wallet (it's not a real wallet)
|
|
514
|
+
// Temporary wallets don't affect walletLoadingState
|
|
515
|
+
log('[useWalletManager] Temporary wallet created successfully')
|
|
516
|
+
} catch (err) {
|
|
517
|
+
const errorMessage = err instanceof Error ? err.message : String(err)
|
|
518
|
+
const errorObj = err instanceof Error ? err : new Error(String(err))
|
|
519
|
+
logError('[useWalletManager] Failed to create temporary wallet:', err)
|
|
520
|
+
setError(errorMessage)
|
|
521
|
+
throw err
|
|
522
|
+
}
|
|
523
|
+
})
|
|
524
|
+
}, [getNetworkConfigs])
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* Check if a wallet exists (for wallet list operations)
|
|
528
|
+
*/
|
|
529
|
+
const checkWallet = useCallback(async (walletId: string): Promise<boolean> => {
|
|
530
|
+
try {
|
|
531
|
+
return await WalletSetupService.hasWallet(walletId)
|
|
532
|
+
} catch (err) {
|
|
533
|
+
logError('Failed to check wallet:', err)
|
|
534
|
+
return false
|
|
535
|
+
}
|
|
536
|
+
}, [])
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* Refresh the wallet list
|
|
540
|
+
*/
|
|
541
|
+
const refreshWalletList = useCallback(async (knownIdentifiers?: string[]) => {
|
|
542
|
+
setIsWalletListLoading(true)
|
|
543
|
+
setWalletListError(null)
|
|
544
|
+
|
|
545
|
+
try {
|
|
546
|
+
const identifiersToCheck = knownIdentifiers || []
|
|
547
|
+
const currentActiveId = walletStore.getState().activeWalletId
|
|
548
|
+
|
|
549
|
+
// If no known identifiers provided, check default wallet
|
|
550
|
+
if (identifiersToCheck.length === 0) {
|
|
551
|
+
const defaultExists = await checkWallet('default')
|
|
552
|
+
walletStore.setState({
|
|
553
|
+
walletList: [{ identifier: 'default', exists: defaultExists, isActive: currentActiveId === 'default' }],
|
|
554
|
+
})
|
|
555
|
+
} else {
|
|
556
|
+
// Check all known identifiers
|
|
557
|
+
const walletChecks = await Promise.all(
|
|
558
|
+
identifiersToCheck.map(async (id) => ({
|
|
559
|
+
identifier: id,
|
|
560
|
+
exists: await checkWallet(id),
|
|
561
|
+
isActive: currentActiveId === id,
|
|
562
|
+
}))
|
|
563
|
+
)
|
|
564
|
+
walletStore.setState({ walletList: walletChecks })
|
|
565
|
+
}
|
|
566
|
+
} catch (err) {
|
|
567
|
+
const errorMessage = err instanceof Error ? err.message : String(err)
|
|
568
|
+
logError('Failed to refresh wallet list:', err)
|
|
569
|
+
setWalletListError(errorMessage)
|
|
570
|
+
} finally {
|
|
571
|
+
setIsWalletListLoading(false)
|
|
572
|
+
}
|
|
573
|
+
}, [checkWallet])
|
|
574
|
+
|
|
575
|
+
|
|
576
|
+
/**
|
|
577
|
+
* Create a new wallet and add it to the wallet list
|
|
578
|
+
*/
|
|
579
|
+
const createWallet = useCallback(async (walletId: string, walletNetworkConfigs?: NetworkConfigs) => {
|
|
580
|
+
setIsWalletListLoading(true)
|
|
581
|
+
setWalletListError(null)
|
|
582
|
+
|
|
583
|
+
try {
|
|
584
|
+
// Check if wallet already exists
|
|
585
|
+
const exists = await checkWallet(walletId)
|
|
586
|
+
if (exists) {
|
|
587
|
+
throw new Error(`Wallet with walletId "${walletId}" already exists`)
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
// Use provided networkConfigs or get from store
|
|
591
|
+
const effectiveNetworkConfigs = walletNetworkConfigs ?? getNetworkConfigs()
|
|
592
|
+
|
|
593
|
+
// Create wallet using WalletSetupService
|
|
594
|
+
await WalletSetupService.createNewWallet(effectiveNetworkConfigs, walletId)
|
|
595
|
+
|
|
596
|
+
// Add to wallet list and set as active wallet
|
|
597
|
+
walletStore.setState((state: import('../store/walletStore').WalletStore) => ({
|
|
598
|
+
walletList: [...state.walletList, { identifier: walletId, exists: true, isActive: true }],
|
|
599
|
+
activeWalletId: walletId, // Set as active wallet so WdkAppProvider can auto-initialize on restart
|
|
600
|
+
}))
|
|
601
|
+
|
|
602
|
+
log(`Created new wallet: ${walletId} and set as active`)
|
|
603
|
+
} catch (err) {
|
|
604
|
+
const errorMessage = err instanceof Error ? err.message : String(err)
|
|
605
|
+
logError('Failed to create wallet:', err)
|
|
606
|
+
setWalletListError(errorMessage)
|
|
607
|
+
throw err
|
|
608
|
+
} finally {
|
|
609
|
+
setIsWalletListLoading(false)
|
|
610
|
+
}
|
|
611
|
+
}, [checkWallet])
|
|
612
|
+
|
|
613
|
+
// Memoize return object to prevent unnecessary re-renders
|
|
614
|
+
return useMemo(
|
|
615
|
+
() => ({
|
|
616
|
+
initializeWallet,
|
|
617
|
+
initializeFromMnemonic,
|
|
618
|
+
hasWallet,
|
|
619
|
+
deleteWallet,
|
|
620
|
+
getMnemonic,
|
|
621
|
+
createTemporaryWallet,
|
|
622
|
+
isInitializing, // Derived from walletLoadingState (single source of truth)
|
|
623
|
+
error,
|
|
624
|
+
clearError,
|
|
625
|
+
clearActiveWallet,
|
|
626
|
+
// Wallet list operations
|
|
627
|
+
wallets: walletListState.wallets,
|
|
628
|
+
activeWalletId: walletListState.activeWalletId,
|
|
629
|
+
createWallet,
|
|
630
|
+
refreshWalletList,
|
|
631
|
+
isWalletListLoading,
|
|
632
|
+
walletListError,
|
|
633
|
+
}),
|
|
634
|
+
[
|
|
635
|
+
initializeWallet,
|
|
636
|
+
initializeFromMnemonic,
|
|
637
|
+
hasWallet,
|
|
638
|
+
deleteWallet,
|
|
639
|
+
getMnemonic,
|
|
640
|
+
createTemporaryWallet,
|
|
641
|
+
isInitializing,
|
|
642
|
+
error,
|
|
643
|
+
clearError,
|
|
644
|
+
clearActiveWallet,
|
|
645
|
+
walletListState.wallets,
|
|
646
|
+
walletListState.activeWalletId,
|
|
647
|
+
createWallet,
|
|
648
|
+
refreshWalletList,
|
|
649
|
+
isWalletListLoading,
|
|
650
|
+
walletListError,
|
|
651
|
+
]
|
|
652
|
+
)
|
|
653
|
+
}
|
|
654
|
+
|