@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,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wallet Switching Service
|
|
3
|
+
*
|
|
4
|
+
* Handles wallet switching operations: checking wallet existence, loading credentials,
|
|
5
|
+
* and initializing WDK with the new wallet.
|
|
6
|
+
*
|
|
7
|
+
* Architecture:
|
|
8
|
+
* - This service is the single source of truth for wallet switching logic
|
|
9
|
+
* - Used by useWallet hook for automatic wallet switching
|
|
10
|
+
* - Can be used by other components that need to switch wallets programmatically
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { WalletSetupService } from './walletSetupService'
|
|
14
|
+
import { WorkletLifecycleService } from './workletLifecycleService'
|
|
15
|
+
import { getWalletStore } from '../store/walletStore'
|
|
16
|
+
import { updateWalletLoadingState, getWalletIdFromLoadingState } from '../store/walletStore'
|
|
17
|
+
import { withOperationMutex } from '../utils/operationMutex'
|
|
18
|
+
import { normalizeError } from '../utils/errorUtils'
|
|
19
|
+
import { log, logError } from '../utils/logger'
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Wallet Switching Service
|
|
23
|
+
*
|
|
24
|
+
* Provides methods for switching between wallets.
|
|
25
|
+
*/
|
|
26
|
+
export class WalletSwitchingService {
|
|
27
|
+
/**
|
|
28
|
+
* Switch to a wallet by identifier
|
|
29
|
+
*
|
|
30
|
+
* This method:
|
|
31
|
+
* 1. Checks if the wallet exists (fail fast)
|
|
32
|
+
* 2. Ensures worklet is started
|
|
33
|
+
* 3. Loads credentials for the wallet
|
|
34
|
+
* 4. Initializes WDK with the credentials
|
|
35
|
+
* 5. Updates activeWalletId in the store
|
|
36
|
+
*
|
|
37
|
+
* @param walletId - Wallet identifier to switch to
|
|
38
|
+
* @param options - Optional configuration
|
|
39
|
+
* @param options.autoStartWorklet - If true, start worklet if not started (default: false)
|
|
40
|
+
* @throws Error if wallet doesn't exist or switching fails
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* await WalletSwitchingService.switchToWallet('user@example.com')
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
static async switchToWallet(
|
|
48
|
+
walletId: string,
|
|
49
|
+
options?: { autoStartWorklet?: boolean }
|
|
50
|
+
): Promise<void> {
|
|
51
|
+
return withOperationMutex(`switchToWallet:${walletId}`, async () => {
|
|
52
|
+
const walletStore = getWalletStore()
|
|
53
|
+
const activeWalletId = walletStore.getState().activeWalletId
|
|
54
|
+
|
|
55
|
+
// Check if already on this wallet
|
|
56
|
+
if (activeWalletId === walletId) {
|
|
57
|
+
log('[WalletSwitchingService] Already on wallet', { walletId })
|
|
58
|
+
return
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
// Update loading state
|
|
63
|
+
walletStore.setState((prev) => updateWalletLoadingState(prev, {
|
|
64
|
+
type: 'loading',
|
|
65
|
+
identifier: walletId,
|
|
66
|
+
walletExists: true,
|
|
67
|
+
}))
|
|
68
|
+
|
|
69
|
+
// Check if wallet exists first (fail fast)
|
|
70
|
+
const walletExists = await WalletSetupService.hasWallet(walletId)
|
|
71
|
+
if (!walletExists) {
|
|
72
|
+
throw new Error(`Wallet with identifier "${walletId}" does not exist`)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Ensure worklet is started
|
|
76
|
+
await WorkletLifecycleService.ensureWorkletStarted(undefined, {
|
|
77
|
+
autoStart: options?.autoStartWorklet ?? false,
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
// Note: We don't clear previous wallet's credentials cache when switching
|
|
81
|
+
// The LRU eviction policy in workletStore will handle cache management
|
|
82
|
+
// This allows users to switch back to recently used wallets without re-authentication
|
|
83
|
+
if (activeWalletId !== null && activeWalletId !== walletId) {
|
|
84
|
+
log('[WalletSwitchingService] Switching wallets', {
|
|
85
|
+
from: activeWalletId,
|
|
86
|
+
to: walletId,
|
|
87
|
+
})
|
|
88
|
+
// Cache is managed by LRU eviction - no need to clear here
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Load credentials for the wallet
|
|
92
|
+
const credentials = await WalletSetupService.loadExistingWallet(walletId)
|
|
93
|
+
|
|
94
|
+
// Switch worklet to this wallet
|
|
95
|
+
await WorkletLifecycleService.initializeWDK({
|
|
96
|
+
encryptionKey: credentials.encryptionKey,
|
|
97
|
+
encryptedSeed: credentials.encryptedSeed,
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
// Update activeWalletId in store and mark as ready
|
|
101
|
+
walletStore.setState((prev) => ({
|
|
102
|
+
...updateWalletLoadingState(prev, {
|
|
103
|
+
type: 'ready',
|
|
104
|
+
identifier: walletId,
|
|
105
|
+
}),
|
|
106
|
+
activeWalletId: walletId,
|
|
107
|
+
}))
|
|
108
|
+
log('[WalletSwitchingService] Successfully switched to wallet', { walletId })
|
|
109
|
+
} catch (error) {
|
|
110
|
+
// Cleanup state on error
|
|
111
|
+
const normalizedError = normalizeError(error, false, {
|
|
112
|
+
component: 'WalletSwitchingService',
|
|
113
|
+
operation: 'switchToWallet',
|
|
114
|
+
walletId,
|
|
115
|
+
})
|
|
116
|
+
logError('[WalletSwitchingService] Failed to switch wallet, cleaning up state', normalizedError)
|
|
117
|
+
|
|
118
|
+
walletStore.setState((prev) => {
|
|
119
|
+
const currentWalletId = getWalletIdFromLoadingState(prev.walletLoadingState)
|
|
120
|
+
// Only update error state if we were loading this wallet
|
|
121
|
+
if (currentWalletId === walletId || prev.walletLoadingState.type === 'loading') {
|
|
122
|
+
return updateWalletLoadingState(prev, {
|
|
123
|
+
type: 'error',
|
|
124
|
+
identifier: walletId,
|
|
125
|
+
error: normalizedError,
|
|
126
|
+
})
|
|
127
|
+
}
|
|
128
|
+
return prev
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
throw normalizedError
|
|
132
|
+
}
|
|
133
|
+
})
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Check if a wallet can be switched to
|
|
138
|
+
*
|
|
139
|
+
* @param walletId - Wallet identifier to check
|
|
140
|
+
* @returns Promise resolving to true if wallet exists and can be switched to
|
|
141
|
+
*/
|
|
142
|
+
static async canSwitchToWallet(walletId: string): Promise<boolean> {
|
|
143
|
+
try {
|
|
144
|
+
return await WalletSetupService.hasWallet(walletId)
|
|
145
|
+
} catch (error) {
|
|
146
|
+
// Log error but don't throw - this is a non-critical check
|
|
147
|
+
const normalizedError = normalizeError(error, false, {
|
|
148
|
+
component: 'WalletSwitchingService',
|
|
149
|
+
operation: 'canSwitchToWallet',
|
|
150
|
+
walletId,
|
|
151
|
+
})
|
|
152
|
+
logError('[WalletSwitchingService] Failed to check wallet:', normalizedError)
|
|
153
|
+
return false
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
@@ -0,0 +1,561 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worklet Lifecycle Service
|
|
3
|
+
*
|
|
4
|
+
* Handles worklet lifecycle operations: starting, initializing, and cleaning up worklets.
|
|
5
|
+
* This service is focused solely on worklet lifecycle management.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { HRPC } from '@spacesops/pear-wrk-wdk'
|
|
9
|
+
import { Worklet } from '@spacesops/react-native-bare-kit'
|
|
10
|
+
|
|
11
|
+
import { getWalletStore } from '../store/walletStore'
|
|
12
|
+
import { getWorkletStore } from '../store/workletStore'
|
|
13
|
+
import { asExtendedHRPC } from '../types/hrpc'
|
|
14
|
+
import { DEFAULT_MNEMONIC_WORD_COUNT } from '../utils/constants'
|
|
15
|
+
import { handleServiceError } from '../utils/errorHandling'
|
|
16
|
+
import { normalizeError } from '../utils/errorUtils'
|
|
17
|
+
import { log, logWarn } from '../utils/logger'
|
|
18
|
+
import { isInitialized as isWorkletInitialized } from '../utils/storeHelpers'
|
|
19
|
+
import type { NetworkConfigs } from '../types'
|
|
20
|
+
import type { WorkletState } from '../store/workletStore'
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Extended HRPC type that may have a cleanup method
|
|
24
|
+
*/
|
|
25
|
+
interface HRPCWithCleanup extends HRPC {
|
|
26
|
+
cleanup?: () => Promise<void> | void
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Extended Worklet type that may have cleanup methods
|
|
31
|
+
*/
|
|
32
|
+
interface WorkletWithCleanup extends Worklet {
|
|
33
|
+
cleanup?: () => Promise<void> | void
|
|
34
|
+
destroy?: () => Promise<void> | void
|
|
35
|
+
stop?: () => Promise<void> | void
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Type guard to check if HRPC has cleanup method
|
|
40
|
+
*/
|
|
41
|
+
function hasHRPCCleanup(hrpc: HRPC): hrpc is HRPCWithCleanup {
|
|
42
|
+
return 'cleanup' in hrpc && typeof (hrpc as Record<string, unknown>).cleanup === 'function'
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Type guard to check if Worklet has cleanup methods
|
|
47
|
+
*/
|
|
48
|
+
function hasWorkletCleanup(worklet: Worklet): worklet is WorkletWithCleanup {
|
|
49
|
+
const w = worklet as unknown as Record<string, unknown>
|
|
50
|
+
return (
|
|
51
|
+
(typeof w.cleanup === 'function') ||
|
|
52
|
+
(typeof w.destroy === 'function') ||
|
|
53
|
+
(typeof w.stop === 'function')
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Worklet Lifecycle Service
|
|
59
|
+
*
|
|
60
|
+
* Provides methods for managing worklet lifecycle: start, initialize, cleanup, reset.
|
|
61
|
+
*/
|
|
62
|
+
export class WorkletLifecycleService {
|
|
63
|
+
/**
|
|
64
|
+
* Cleanup a resource by trying cleanup methods in order
|
|
65
|
+
* Handles cleanup gracefully, continuing even if individual steps fail
|
|
66
|
+
*/
|
|
67
|
+
private static async cleanupResource(
|
|
68
|
+
resource: HRPC | Worklet | null,
|
|
69
|
+
cleanupMethods: string[]
|
|
70
|
+
): Promise<void> {
|
|
71
|
+
if (!resource) return
|
|
72
|
+
|
|
73
|
+
const r = resource as unknown as Record<string, unknown>
|
|
74
|
+
const method = cleanupMethods.find((m) => typeof r[m] === 'function')
|
|
75
|
+
if (method) {
|
|
76
|
+
try {
|
|
77
|
+
await (r[method] as () => Promise<void> | void)()
|
|
78
|
+
} catch (error) {
|
|
79
|
+
logWarn(`Error calling ${method} on resource:`, error)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Cleanup worklet resources (HRPC and Worklet instances)
|
|
86
|
+
* Handles cleanup gracefully, continuing even if individual steps fail
|
|
87
|
+
*/
|
|
88
|
+
private static async cleanupWorkletResources(
|
|
89
|
+
hrpc: HRPC | null,
|
|
90
|
+
worklet: Worklet | null
|
|
91
|
+
): Promise<void> {
|
|
92
|
+
try {
|
|
93
|
+
// Cleanup HRPC if it has a cleanup method
|
|
94
|
+
await this.cleanupResource(hrpc, ['cleanup'])
|
|
95
|
+
|
|
96
|
+
// Cleanup worklet - try cleanup, destroy, or stop in that order
|
|
97
|
+
await this.cleanupResource(worklet, ['cleanup', 'destroy', 'stop'])
|
|
98
|
+
} catch (error) {
|
|
99
|
+
logWarn('Error cleaning up worklet resources:', error)
|
|
100
|
+
// Continue even if cleanup fails
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Start the worklet with network configurations
|
|
105
|
+
*/
|
|
106
|
+
static async startWorklet(
|
|
107
|
+
networkConfigs: NetworkConfigs
|
|
108
|
+
): Promise<void> {
|
|
109
|
+
const store = getWorkletStore()
|
|
110
|
+
const state = store.getState()
|
|
111
|
+
|
|
112
|
+
if (state.isLoading) {
|
|
113
|
+
logWarn('Worklet initialization already in progress')
|
|
114
|
+
return
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (state.isWorkletStarted) {
|
|
118
|
+
log('Worklet already started')
|
|
119
|
+
return
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
try {
|
|
123
|
+
store.setState({
|
|
124
|
+
error: null,
|
|
125
|
+
isLoading: true,
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
// Cleanup existing worklet if present
|
|
129
|
+
const { worklet: existingWorklet, hrpc: existingHrpc } = store.getState()
|
|
130
|
+
if (existingWorklet || existingHrpc) {
|
|
131
|
+
await this.cleanupWorkletResources(existingHrpc, existingWorklet)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const worklet = new Worklet()
|
|
135
|
+
|
|
136
|
+
// Dynamic import of @spacesops/pear-wrk-wdk bundle
|
|
137
|
+
const pearWrkWdk = await import('@spacesops/pear-wrk-wdk')
|
|
138
|
+
const bundle = (pearWrkWdk as { bundle?: unknown }).bundle
|
|
139
|
+
|
|
140
|
+
if (!bundle) {
|
|
141
|
+
throw new Error('Failed to load @spacesops/pear-wrk-wdk bundle')
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Bundle file (mobile bundle for React Native) - worklet.start expects bundle parameter
|
|
145
|
+
;(worklet.start as (path: string, bundle: unknown) => void)('/wdk-worklet.bundle', bundle)
|
|
146
|
+
|
|
147
|
+
const { IPC } = worklet
|
|
148
|
+
|
|
149
|
+
if (!IPC) {
|
|
150
|
+
throw new Error('IPC not available from worklet')
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const hrpcInstance = new HRPC(IPC)
|
|
154
|
+
|
|
155
|
+
const result = await hrpcInstance.workletStart({
|
|
156
|
+
config: JSON.stringify(networkConfigs),
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
store.setState({
|
|
160
|
+
worklet,
|
|
161
|
+
hrpc: hrpcInstance,
|
|
162
|
+
ipc: IPC,
|
|
163
|
+
isWorkletStarted: true,
|
|
164
|
+
isLoading: false,
|
|
165
|
+
networkConfigs,
|
|
166
|
+
workletStartResult: result,
|
|
167
|
+
error: null,
|
|
168
|
+
})
|
|
169
|
+
} catch (error) {
|
|
170
|
+
this.handleErrorWithStateUpdate(
|
|
171
|
+
error,
|
|
172
|
+
'startWorklet',
|
|
173
|
+
(normalizedError) => ({
|
|
174
|
+
error: normalizedError.message,
|
|
175
|
+
isLoading: false,
|
|
176
|
+
worklet: null,
|
|
177
|
+
hrpc: null,
|
|
178
|
+
ipc: null,
|
|
179
|
+
isWorkletStarted: false,
|
|
180
|
+
})
|
|
181
|
+
)
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Ensure worklet is started, starting it if needed
|
|
187
|
+
*
|
|
188
|
+
* @param networkConfigs - Network configs (required if autoStart=true)
|
|
189
|
+
* @param options - Options
|
|
190
|
+
* @param options.autoStart - If true, start worklet if not started (default: false)
|
|
191
|
+
* @throws Error if worklet not started and autoStart=false or networkConfigs not provided
|
|
192
|
+
*/
|
|
193
|
+
static async ensureWorkletStarted(
|
|
194
|
+
networkConfigs?: NetworkConfigs,
|
|
195
|
+
options?: { autoStart?: boolean }
|
|
196
|
+
): Promise<void> {
|
|
197
|
+
const store = getWorkletStore()
|
|
198
|
+
const state = store.getState()
|
|
199
|
+
|
|
200
|
+
if (state.isWorkletStarted) {
|
|
201
|
+
return // Already started
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const autoStart = options?.autoStart ?? false
|
|
205
|
+
if (!autoStart || !networkConfigs) {
|
|
206
|
+
throw new Error('Worklet must be started before this operation')
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
await this.startWorklet(networkConfigs)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Initialize WDK with encrypted seed (ONLY encrypted approach)
|
|
214
|
+
*/
|
|
215
|
+
static async initializeWDK(
|
|
216
|
+
options: { encryptionKey: string; encryptedSeed: string }
|
|
217
|
+
): Promise<void> {
|
|
218
|
+
const store = getWorkletStore()
|
|
219
|
+
const state = store.getState()
|
|
220
|
+
|
|
221
|
+
if (!state.isWorkletStarted) {
|
|
222
|
+
throw new Error('Worklet must be started before initializing WDK')
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (
|
|
226
|
+
state.isInitialized &&
|
|
227
|
+
state.encryptionKey === options.encryptionKey &&
|
|
228
|
+
state.encryptedSeed === options.encryptedSeed
|
|
229
|
+
) {
|
|
230
|
+
log('WDK already initialized with the same encrypted seed')
|
|
231
|
+
return
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
try {
|
|
235
|
+
store.setState({
|
|
236
|
+
error: null,
|
|
237
|
+
isLoading: true,
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
// Get HRPC directly from store instead of using requireExtendedHRPC()
|
|
241
|
+
// requireExtendedHRPC() requires isInitialized to be true, but we're setting it here
|
|
242
|
+
const currentState = store.getState()
|
|
243
|
+
if (!currentState.hrpc) {
|
|
244
|
+
throw new Error('HRPC instance not available. Worklet may not be fully started.')
|
|
245
|
+
}
|
|
246
|
+
const extendedHrpc = asExtendedHRPC(currentState.hrpc)
|
|
247
|
+
const result = await extendedHrpc.initializeWDK({
|
|
248
|
+
encryptionKey: options.encryptionKey,
|
|
249
|
+
encryptedSeed: options.encryptedSeed,
|
|
250
|
+
config: JSON.stringify(currentState.networkConfigs || {}),
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
// NEVER store seed phrase
|
|
254
|
+
// Extract status from result
|
|
255
|
+
const wdkInitResult = this.extractWdkInitResult(result)
|
|
256
|
+
|
|
257
|
+
store.setState({
|
|
258
|
+
isInitialized: true,
|
|
259
|
+
isLoading: false,
|
|
260
|
+
encryptedSeed: options.encryptedSeed,
|
|
261
|
+
encryptionKey: options.encryptionKey,
|
|
262
|
+
wdkInitResult,
|
|
263
|
+
error: null,
|
|
264
|
+
})
|
|
265
|
+
} catch (error) {
|
|
266
|
+
this.handleErrorWithStateUpdate(
|
|
267
|
+
error,
|
|
268
|
+
'initializeWDK',
|
|
269
|
+
(normalizedError) => ({
|
|
270
|
+
error: normalizedError.message,
|
|
271
|
+
isLoading: false,
|
|
272
|
+
isInitialized: false,
|
|
273
|
+
})
|
|
274
|
+
)
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Generate entropy and encrypt (for creating new wallets)
|
|
280
|
+
*/
|
|
281
|
+
static async generateEntropyAndEncrypt(
|
|
282
|
+
wordCount: 12 | 24 = DEFAULT_MNEMONIC_WORD_COUNT
|
|
283
|
+
): Promise<{
|
|
284
|
+
encryptionKey: string
|
|
285
|
+
encryptedSeedBuffer: string
|
|
286
|
+
encryptedEntropyBuffer: string
|
|
287
|
+
}> {
|
|
288
|
+
const store = getWorkletStore()
|
|
289
|
+
const state = store.getState()
|
|
290
|
+
|
|
291
|
+
if (!state.isWorkletStarted) {
|
|
292
|
+
throw new Error('Worklet must be started before generating entropy')
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
try {
|
|
296
|
+
// Get HRPC directly from store instead of using requireExtendedHRPC()
|
|
297
|
+
// These methods may be called before WDK is initialized
|
|
298
|
+
const currentState = store.getState()
|
|
299
|
+
if (!currentState.hrpc) {
|
|
300
|
+
throw new Error('HRPC instance not available. Worklet may not be fully started.')
|
|
301
|
+
}
|
|
302
|
+
const extendedHrpc = asExtendedHRPC(currentState.hrpc)
|
|
303
|
+
const result = await extendedHrpc.generateEntropyAndEncrypt({
|
|
304
|
+
wordCount,
|
|
305
|
+
})
|
|
306
|
+
|
|
307
|
+
return {
|
|
308
|
+
encryptionKey: result.encryptionKey,
|
|
309
|
+
encryptedSeedBuffer: result.encryptedSeedBuffer,
|
|
310
|
+
encryptedEntropyBuffer: result.encryptedEntropyBuffer,
|
|
311
|
+
}
|
|
312
|
+
} catch (error) {
|
|
313
|
+
this.handleAndThrowError(error, 'generateEntropyAndEncrypt', 'Failed to generate entropy')
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Get mnemonic from encrypted entropy (for display purposes only - never stored)
|
|
319
|
+
*/
|
|
320
|
+
static async getMnemonicFromEntropy(
|
|
321
|
+
encryptedEntropy: string,
|
|
322
|
+
encryptionKey: string
|
|
323
|
+
): Promise<{
|
|
324
|
+
mnemonic: string
|
|
325
|
+
}> {
|
|
326
|
+
const store = getWorkletStore()
|
|
327
|
+
const state = store.getState()
|
|
328
|
+
|
|
329
|
+
if (!state.isWorkletStarted) {
|
|
330
|
+
throw new Error('Worklet must be started before getting mnemonic')
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
try {
|
|
334
|
+
// Get HRPC directly from store instead of using requireExtendedHRPC()
|
|
335
|
+
// These methods may be called before WDK is initialized
|
|
336
|
+
const currentState = store.getState()
|
|
337
|
+
if (!currentState.hrpc) {
|
|
338
|
+
throw new Error('HRPC instance not available. Worklet may not be fully started.')
|
|
339
|
+
}
|
|
340
|
+
const extendedHrpc = asExtendedHRPC(currentState.hrpc)
|
|
341
|
+
|
|
342
|
+
const result = await extendedHrpc.getMnemonicFromEntropy({
|
|
343
|
+
encryptedEntropy,
|
|
344
|
+
encryptionKey,
|
|
345
|
+
})
|
|
346
|
+
|
|
347
|
+
return {
|
|
348
|
+
mnemonic: result.mnemonic,
|
|
349
|
+
}
|
|
350
|
+
} catch (error) {
|
|
351
|
+
this.handleAndThrowError(error, 'getMnemonicFromEntropy', 'Failed to get mnemonic')
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Get seed and entropy from mnemonic phrase (for importing existing wallets)
|
|
357
|
+
*/
|
|
358
|
+
static async getSeedAndEntropyFromMnemonic(
|
|
359
|
+
mnemonic: string
|
|
360
|
+
): Promise<{
|
|
361
|
+
encryptionKey: string
|
|
362
|
+
encryptedSeedBuffer: string
|
|
363
|
+
encryptedEntropyBuffer: string
|
|
364
|
+
}> {
|
|
365
|
+
const store = getWorkletStore()
|
|
366
|
+
const state = store.getState()
|
|
367
|
+
|
|
368
|
+
if (!state.isWorkletStarted) {
|
|
369
|
+
throw new Error('Worklet must be started before getting seed and entropy from mnemonic')
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
try {
|
|
373
|
+
// Get HRPC directly from store instead of using requireExtendedHRPC()
|
|
374
|
+
// These methods may be called before WDK is initialized
|
|
375
|
+
const currentState = store.getState()
|
|
376
|
+
if (!currentState.hrpc) {
|
|
377
|
+
throw new Error('HRPC instance not available. Worklet may not be fully started.')
|
|
378
|
+
}
|
|
379
|
+
const extendedHrpc = asExtendedHRPC(currentState.hrpc)
|
|
380
|
+
const result = await extendedHrpc.getSeedAndEntropyFromMnemonic({
|
|
381
|
+
mnemonic,
|
|
382
|
+
})
|
|
383
|
+
|
|
384
|
+
return {
|
|
385
|
+
encryptionKey: result.encryptionKey,
|
|
386
|
+
encryptedSeedBuffer: result.encryptedSeedBuffer,
|
|
387
|
+
encryptedEntropyBuffer: result.encryptedEntropyBuffer,
|
|
388
|
+
}
|
|
389
|
+
} catch (error) {
|
|
390
|
+
this.handleAndThrowError(
|
|
391
|
+
error,
|
|
392
|
+
'getSeedAndEntropyFromMnemonic',
|
|
393
|
+
'Failed to get seed and entropy from mnemonic'
|
|
394
|
+
)
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Initialize both worklet and WDK in one call (convenience method) - ONLY encrypted
|
|
400
|
+
*/
|
|
401
|
+
static async initializeWorklet(
|
|
402
|
+
options: {
|
|
403
|
+
encryptionKey: string
|
|
404
|
+
encryptedSeed: string
|
|
405
|
+
networkConfigs: NetworkConfigs
|
|
406
|
+
}
|
|
407
|
+
): Promise<void> {
|
|
408
|
+
// Convenience method that does both steps - ONLY encrypted approach
|
|
409
|
+
await this.startWorklet(options.networkConfigs)
|
|
410
|
+
await this.initializeWDK({
|
|
411
|
+
encryptionKey: options.encryptionKey,
|
|
412
|
+
encryptedSeed: options.encryptedSeed,
|
|
413
|
+
})
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Handle error for methods that throw with a message prefix
|
|
418
|
+
* Normalizes error, logs it, and throws a new error with operation context
|
|
419
|
+
*/
|
|
420
|
+
private static handleAndThrowError(
|
|
421
|
+
error: unknown,
|
|
422
|
+
operation: string,
|
|
423
|
+
errorMessagePrefix: string
|
|
424
|
+
): never {
|
|
425
|
+
const normalizedError = normalizeError(error, false, {
|
|
426
|
+
component: 'WorkletLifecycleService',
|
|
427
|
+
operation,
|
|
428
|
+
})
|
|
429
|
+
handleServiceError(error, 'WorkletLifecycleService', operation)
|
|
430
|
+
throw new Error(`${errorMessagePrefix}: ${normalizedError.message}`)
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Handle error for methods that update store state
|
|
435
|
+
* Normalizes error, updates store state, and re-throws
|
|
436
|
+
*/
|
|
437
|
+
private static handleErrorWithStateUpdate(
|
|
438
|
+
error: unknown,
|
|
439
|
+
operation: string,
|
|
440
|
+
stateUpdate: (normalizedError: Error) => Partial<WorkletState>
|
|
441
|
+
): never {
|
|
442
|
+
const normalizedError = normalizeError(error, false, {
|
|
443
|
+
component: 'WorkletLifecycleService',
|
|
444
|
+
operation,
|
|
445
|
+
})
|
|
446
|
+
const store = getWorkletStore()
|
|
447
|
+
store.setState(stateUpdate(normalizedError))
|
|
448
|
+
handleServiceError(error, 'WorkletLifecycleService', operation)
|
|
449
|
+
throw normalizedError
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Extract WDK initialization result status
|
|
454
|
+
* Safely extracts status from result object
|
|
455
|
+
*/
|
|
456
|
+
private static extractWdkInitResult(result: unknown): { status?: string | null } | null {
|
|
457
|
+
if (result && typeof result === 'object' && 'status' in result) {
|
|
458
|
+
const status = (result as { status?: unknown }).status
|
|
459
|
+
if (status === null || status === undefined || typeof status === 'string') {
|
|
460
|
+
return { status: status ?? null }
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
return null
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Reset both worklet and wallet stores
|
|
468
|
+
*/
|
|
469
|
+
private static resetStores(): void {
|
|
470
|
+
const workletStore = getWorkletStore()
|
|
471
|
+
const walletStore = getWalletStore()
|
|
472
|
+
|
|
473
|
+
workletStore.setState({
|
|
474
|
+
worklet: null,
|
|
475
|
+
hrpc: null,
|
|
476
|
+
ipc: null,
|
|
477
|
+
isWorkletStarted: false,
|
|
478
|
+
isInitialized: false,
|
|
479
|
+
isLoading: false,
|
|
480
|
+
error: null,
|
|
481
|
+
encryptedSeed: null,
|
|
482
|
+
encryptionKey: null,
|
|
483
|
+
networkConfigs: null,
|
|
484
|
+
workletStartResult: null,
|
|
485
|
+
wdkInitResult: null,
|
|
486
|
+
})
|
|
487
|
+
walletStore.setState({
|
|
488
|
+
addresses: {},
|
|
489
|
+
walletLoading: {},
|
|
490
|
+
balances: {},
|
|
491
|
+
balanceLoading: {},
|
|
492
|
+
lastBalanceUpdate: {},
|
|
493
|
+
})
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Cleanup worklet resources
|
|
498
|
+
* Clears only addresses, seed, and WDK instance - does NOT terminate the worklet
|
|
499
|
+
* The worklet continues running for faster re-initialization
|
|
500
|
+
*/
|
|
501
|
+
static async cleanup(): Promise<void> {
|
|
502
|
+
const workletStore = getWorkletStore()
|
|
503
|
+
const walletStore = getWalletStore()
|
|
504
|
+
|
|
505
|
+
// Clear only sensitive data - addresses, seed, and WDK instance
|
|
506
|
+
// Do NOT terminate worklet, hrpc, or ipc - keep them running
|
|
507
|
+
workletStore.setState({
|
|
508
|
+
encryptedSeed: null,
|
|
509
|
+
encryptionKey: null,
|
|
510
|
+
isInitialized: false,
|
|
511
|
+
wdkInitResult: null,
|
|
512
|
+
})
|
|
513
|
+
|
|
514
|
+
// Clear addresses from wallet store
|
|
515
|
+
walletStore.setState({
|
|
516
|
+
addresses: {},
|
|
517
|
+
})
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/**
|
|
521
|
+
* Reset worklet state (synchronous)
|
|
522
|
+
* Clears only addresses, seed, and WDK instance - does NOT terminate the worklet
|
|
523
|
+
* The worklet continues running for faster re-initialization
|
|
524
|
+
* For async cleanup, use cleanup() instead
|
|
525
|
+
*/
|
|
526
|
+
static reset(): void {
|
|
527
|
+
const workletStore = getWorkletStore()
|
|
528
|
+
const walletStore = getWalletStore()
|
|
529
|
+
|
|
530
|
+
// Clear only sensitive data - addresses, seed, and WDK instance
|
|
531
|
+
// Do NOT terminate worklet, hrpc, or ipc - keep them running
|
|
532
|
+
workletStore.setState({
|
|
533
|
+
encryptedSeed: null,
|
|
534
|
+
encryptionKey: null,
|
|
535
|
+
isInitialized: false,
|
|
536
|
+
wdkInitResult: null,
|
|
537
|
+
})
|
|
538
|
+
|
|
539
|
+
// Clear addresses from wallet store
|
|
540
|
+
walletStore.setState({
|
|
541
|
+
addresses: {},
|
|
542
|
+
})
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* Clear error state
|
|
547
|
+
*/
|
|
548
|
+
static clearError(): void {
|
|
549
|
+
const store = getWorkletStore()
|
|
550
|
+
store.setState({ error: null })
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* Check if wallet is initialized
|
|
555
|
+
* Returns true if worklet is started and WDK is initialized
|
|
556
|
+
*/
|
|
557
|
+
static isInitialized(): boolean {
|
|
558
|
+
return isWorkletInitialized()
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
|