@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,463 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for WalletSetupService
|
|
3
|
+
*
|
|
4
|
+
* Tests wallet creation, loading, and identifier-based multi-wallet support
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { WalletSetupService } from '../../services/walletSetupService'
|
|
8
|
+
import { mockSecureStorage } from '../../__mocks__/secureStorage'
|
|
9
|
+
import { WorkletLifecycleService } from '../../services/workletLifecycleService'
|
|
10
|
+
import { getWorkletStore } from '../../store/workletStore'
|
|
11
|
+
import type { NetworkConfigs } from '../../types'
|
|
12
|
+
|
|
13
|
+
// Mock WorkletLifecycleService
|
|
14
|
+
jest.mock('../../services/workletLifecycleService', () => ({
|
|
15
|
+
WorkletLifecycleService: {
|
|
16
|
+
startWorklet: jest.fn(() => Promise.resolve()),
|
|
17
|
+
generateEntropyAndEncrypt: jest.fn(() => Promise.resolve({
|
|
18
|
+
encryptionKey: 'test-encryption-key',
|
|
19
|
+
encryptedSeedBuffer: 'test-encrypted-seed',
|
|
20
|
+
encryptedEntropyBuffer: 'test-encrypted-entropy',
|
|
21
|
+
})),
|
|
22
|
+
getSeedAndEntropyFromMnemonic: jest.fn(() => Promise.resolve({
|
|
23
|
+
encryptionKey: 'test-encryption-key',
|
|
24
|
+
encryptedSeedBuffer: 'test-encrypted-seed-from-mnemonic',
|
|
25
|
+
encryptedEntropyBuffer: 'test-encrypted-entropy-from-mnemonic',
|
|
26
|
+
})),
|
|
27
|
+
initializeWDK: jest.fn(() => Promise.resolve()),
|
|
28
|
+
reset: jest.fn(),
|
|
29
|
+
},
|
|
30
|
+
}))
|
|
31
|
+
|
|
32
|
+
// Mock workletStore
|
|
33
|
+
jest.mock('../../store/workletStore', () => ({
|
|
34
|
+
getWorkletStore: jest.fn(() => ({
|
|
35
|
+
getState: jest.fn(() => ({
|
|
36
|
+
isWorkletStarted: true,
|
|
37
|
+
isInitialized: false,
|
|
38
|
+
credentialsCache: {},
|
|
39
|
+
})),
|
|
40
|
+
setState: jest.fn(),
|
|
41
|
+
})),
|
|
42
|
+
getCachedCredentials: jest.fn(() => null),
|
|
43
|
+
setCachedCredentials: jest.fn(),
|
|
44
|
+
clearCredentialsCache: jest.fn(),
|
|
45
|
+
}))
|
|
46
|
+
|
|
47
|
+
describe('WalletSetupService', () => {
|
|
48
|
+
const mockNetworkConfigs: NetworkConfigs = {
|
|
49
|
+
ethereum: {
|
|
50
|
+
chainId: 1,
|
|
51
|
+
blockchain: 'ethereum',
|
|
52
|
+
},
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
beforeEach(() => {
|
|
56
|
+
jest.clearAllMocks()
|
|
57
|
+
// Set the secureStorage instance for testing
|
|
58
|
+
WalletSetupService.setSecureStorage(mockSecureStorage, true)
|
|
59
|
+
// Clear mock storage between tests
|
|
60
|
+
if (typeof (mockSecureStorage as any)._clearStorage === 'function') {
|
|
61
|
+
(mockSecureStorage as any)._clearStorage()
|
|
62
|
+
}
|
|
63
|
+
// Clear credentials cache between tests
|
|
64
|
+
WalletSetupService.clearCredentialsCache()
|
|
65
|
+
// Reset worklet store mock - default state
|
|
66
|
+
const mockStore = getWorkletStore() as any
|
|
67
|
+
if (mockStore) {
|
|
68
|
+
mockStore.getState = jest.fn(() => ({
|
|
69
|
+
isWorkletStarted: true,
|
|
70
|
+
isInitialized: false,
|
|
71
|
+
}))
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
describe('createNewWallet', () => {
|
|
76
|
+
it('should create a new wallet without identifier', async () => {
|
|
77
|
+
const result = await WalletSetupService.createNewWallet(
|
|
78
|
+
mockNetworkConfigs
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
expect(result).toHaveProperty('encryptionKey')
|
|
82
|
+
expect(result).toHaveProperty('encryptedSeed')
|
|
83
|
+
expect(mockSecureStorage.authenticate).toHaveBeenCalled()
|
|
84
|
+
expect(mockSecureStorage.setEncryptionKey).toHaveBeenCalledWith(
|
|
85
|
+
'test-encryption-key',
|
|
86
|
+
undefined
|
|
87
|
+
)
|
|
88
|
+
expect(mockSecureStorage.setEncryptedSeed).toHaveBeenCalledWith(
|
|
89
|
+
'test-encrypted-seed',
|
|
90
|
+
undefined
|
|
91
|
+
)
|
|
92
|
+
expect(mockSecureStorage.setEncryptedEntropy).toHaveBeenCalledWith(
|
|
93
|
+
'test-encrypted-entropy',
|
|
94
|
+
undefined
|
|
95
|
+
)
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
it('should create a new wallet with identifier', async () => {
|
|
99
|
+
const identifier = 'user@example.com'
|
|
100
|
+
const result = await WalletSetupService.createNewWallet(
|
|
101
|
+
mockNetworkConfigs,
|
|
102
|
+
identifier
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
expect(result).toHaveProperty('encryptionKey')
|
|
106
|
+
expect(result).toHaveProperty('encryptedSeed')
|
|
107
|
+
expect(mockSecureStorage.setEncryptionKey).toHaveBeenCalledWith(
|
|
108
|
+
'test-encryption-key',
|
|
109
|
+
identifier
|
|
110
|
+
)
|
|
111
|
+
expect(mockSecureStorage.setEncryptedSeed).toHaveBeenCalledWith(
|
|
112
|
+
'test-encrypted-seed',
|
|
113
|
+
identifier
|
|
114
|
+
)
|
|
115
|
+
expect(mockSecureStorage.setEncryptedEntropy).toHaveBeenCalledWith(
|
|
116
|
+
'test-encrypted-entropy',
|
|
117
|
+
identifier
|
|
118
|
+
)
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
it('should require biometric authentication', async () => {
|
|
122
|
+
const authMock = mockSecureStorage.authenticate as jest.Mock
|
|
123
|
+
authMock.mockResolvedValueOnce(false)
|
|
124
|
+
|
|
125
|
+
await expect(
|
|
126
|
+
WalletSetupService.createNewWallet(mockNetworkConfigs)
|
|
127
|
+
).rejects.toThrow('Biometric authentication required to create wallet')
|
|
128
|
+
})
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
describe('loadExistingWallet', () => {
|
|
132
|
+
it('should load existing wallet without identifier', async () => {
|
|
133
|
+
// Setup: create a wallet first
|
|
134
|
+
await mockSecureStorage.setEncryptionKey('test-key', undefined)
|
|
135
|
+
await mockSecureStorage.setEncryptedSeed('test-seed', undefined)
|
|
136
|
+
|
|
137
|
+
const result = await WalletSetupService.loadExistingWallet()
|
|
138
|
+
|
|
139
|
+
expect(result).toHaveProperty('encryptionKey', 'test-key')
|
|
140
|
+
expect(result).toHaveProperty('encryptedSeed', 'test-seed')
|
|
141
|
+
expect(mockSecureStorage.getEncryptedSeed).toHaveBeenCalledWith(undefined)
|
|
142
|
+
expect(mockSecureStorage.getAllEncrypted).toHaveBeenCalledWith(undefined)
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
it('should load existing wallet with identifier', async () => {
|
|
146
|
+
const identifier = 'user@example.com'
|
|
147
|
+
// Setup: create a wallet with identifier
|
|
148
|
+
await mockSecureStorage.setEncryptionKey('test-key', identifier)
|
|
149
|
+
await mockSecureStorage.setEncryptedSeed('test-seed', identifier)
|
|
150
|
+
|
|
151
|
+
const result = await WalletSetupService.loadExistingWallet(identifier)
|
|
152
|
+
|
|
153
|
+
expect(result).toHaveProperty('encryptionKey', 'test-key')
|
|
154
|
+
expect(result).toHaveProperty('encryptedSeed', 'test-seed')
|
|
155
|
+
expect(mockSecureStorage.getEncryptedSeed).toHaveBeenCalledWith(identifier)
|
|
156
|
+
expect(mockSecureStorage.getAllEncrypted).toHaveBeenCalledWith(identifier)
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
it('should throw error if encryption key not found', async () => {
|
|
160
|
+
// Ensure cache is clear and storage is empty
|
|
161
|
+
WalletSetupService.clearCredentialsCache()
|
|
162
|
+
await mockSecureStorage.clearAll()
|
|
163
|
+
|
|
164
|
+
await expect(
|
|
165
|
+
WalletSetupService.loadExistingWallet()
|
|
166
|
+
).rejects.toThrow('Encryption key not found')
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
it('should throw error if encrypted seed not found', async () => {
|
|
170
|
+
// Ensure cache is clear
|
|
171
|
+
WalletSetupService.clearCredentialsCache()
|
|
172
|
+
await mockSecureStorage.setEncryptionKey('test-key', undefined)
|
|
173
|
+
// Don't set seed
|
|
174
|
+
|
|
175
|
+
await expect(
|
|
176
|
+
WalletSetupService.loadExistingWallet()
|
|
177
|
+
).rejects.toThrow('Encrypted seed not found')
|
|
178
|
+
})
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
describe('hasWallet', () => {
|
|
182
|
+
it('should return false when no wallet exists', async () => {
|
|
183
|
+
const result = await WalletSetupService.hasWallet()
|
|
184
|
+
expect(result).toBe(false)
|
|
185
|
+
expect(mockSecureStorage.hasWallet).toHaveBeenCalledWith(undefined)
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
it('should return true when wallet exists', async () => {
|
|
189
|
+
await mockSecureStorage.setEncryptionKey('test-key', undefined)
|
|
190
|
+
const result = await WalletSetupService.hasWallet()
|
|
191
|
+
expect(result).toBe(true)
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
it('should check wallet with identifier', async () => {
|
|
195
|
+
const identifier = 'user@example.com'
|
|
196
|
+
await mockSecureStorage.setEncryptionKey('test-key', identifier)
|
|
197
|
+
const result = await WalletSetupService.hasWallet(identifier)
|
|
198
|
+
expect(result).toBe(true)
|
|
199
|
+
expect(mockSecureStorage.hasWallet).toHaveBeenCalledWith(identifier)
|
|
200
|
+
})
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
describe('initializeFromMnemonic', () => {
|
|
204
|
+
const testMnemonic = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about'
|
|
205
|
+
|
|
206
|
+
it('should initialize wallet from mnemonic without identifier', async () => {
|
|
207
|
+
const result = await WalletSetupService.initializeFromMnemonic(
|
|
208
|
+
mockNetworkConfigs,
|
|
209
|
+
testMnemonic
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
expect(result).toHaveProperty('encryptionKey')
|
|
213
|
+
expect(result).toHaveProperty('encryptedSeed')
|
|
214
|
+
expect(result).toHaveProperty('encryptedEntropy')
|
|
215
|
+
expect(mockSecureStorage.setEncryptionKey).toHaveBeenCalledWith(
|
|
216
|
+
'test-encryption-key',
|
|
217
|
+
undefined
|
|
218
|
+
)
|
|
219
|
+
expect(WorkletLifecycleService.initializeWDK).toHaveBeenCalled()
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
it('should initialize wallet from mnemonic with identifier', async () => {
|
|
223
|
+
const identifier = 'user@example.com'
|
|
224
|
+
const result = await WalletSetupService.initializeFromMnemonic(
|
|
225
|
+
mockNetworkConfigs,
|
|
226
|
+
testMnemonic,
|
|
227
|
+
identifier
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
expect(result).toHaveProperty('encryptionKey')
|
|
231
|
+
expect(mockSecureStorage.setEncryptionKey).toHaveBeenCalledWith(
|
|
232
|
+
'test-encryption-key',
|
|
233
|
+
identifier
|
|
234
|
+
)
|
|
235
|
+
expect(mockSecureStorage.setEncryptedSeed).toHaveBeenCalledWith(
|
|
236
|
+
'test-encrypted-seed-from-mnemonic',
|
|
237
|
+
identifier
|
|
238
|
+
)
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
it('should require biometric authentication', async () => {
|
|
242
|
+
const authMock = mockSecureStorage.authenticate as jest.Mock
|
|
243
|
+
authMock.mockResolvedValueOnce(false)
|
|
244
|
+
|
|
245
|
+
await expect(
|
|
246
|
+
WalletSetupService.initializeFromMnemonic(
|
|
247
|
+
mockNetworkConfigs,
|
|
248
|
+
testMnemonic
|
|
249
|
+
)
|
|
250
|
+
).rejects.toThrow('Biometric authentication required to import wallet')
|
|
251
|
+
})
|
|
252
|
+
})
|
|
253
|
+
|
|
254
|
+
describe('initializeWallet', () => {
|
|
255
|
+
it('should create new wallet when createNew is true', async () => {
|
|
256
|
+
const mockStore = getWorkletStore() as any
|
|
257
|
+
mockStore.getState = jest.fn(() => ({
|
|
258
|
+
isWorkletStarted: true,
|
|
259
|
+
isInitialized: false,
|
|
260
|
+
}))
|
|
261
|
+
|
|
262
|
+
await WalletSetupService.initializeWallet(
|
|
263
|
+
mockNetworkConfigs,
|
|
264
|
+
{ createNew: true }
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
expect(mockSecureStorage.setEncryptionKey).toHaveBeenCalled()
|
|
268
|
+
expect(WorkletLifecycleService.initializeWDK).toHaveBeenCalled()
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
it('should load existing wallet when createNew is false', async () => {
|
|
272
|
+
const mockStore = getWorkletStore() as any
|
|
273
|
+
mockStore.getState = jest.fn(() => ({
|
|
274
|
+
isWorkletStarted: true,
|
|
275
|
+
isInitialized: false,
|
|
276
|
+
}))
|
|
277
|
+
|
|
278
|
+
// Ensure cache is clear
|
|
279
|
+
WalletSetupService.clearCredentialsCache()
|
|
280
|
+
|
|
281
|
+
// Setup: create a wallet first
|
|
282
|
+
await mockSecureStorage.setEncryptionKey('test-key', undefined)
|
|
283
|
+
await mockSecureStorage.setEncryptedSeed('test-seed', undefined)
|
|
284
|
+
|
|
285
|
+
await WalletSetupService.initializeWallet(
|
|
286
|
+
mockNetworkConfigs,
|
|
287
|
+
{ createNew: false }
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
expect(mockSecureStorage.getEncryptedSeed).toHaveBeenCalled()
|
|
291
|
+
expect(mockSecureStorage.getAllEncrypted).toHaveBeenCalled()
|
|
292
|
+
expect(WorkletLifecycleService.initializeWDK).toHaveBeenCalled()
|
|
293
|
+
})
|
|
294
|
+
|
|
295
|
+
it('should pass identifier when creating new wallet', async () => {
|
|
296
|
+
const mockStore = getWorkletStore() as any
|
|
297
|
+
mockStore.getState = jest.fn(() => ({
|
|
298
|
+
isWorkletStarted: true,
|
|
299
|
+
isInitialized: false,
|
|
300
|
+
}))
|
|
301
|
+
|
|
302
|
+
const identifier = 'user@example.com'
|
|
303
|
+
await WalletSetupService.initializeWallet(
|
|
304
|
+
mockNetworkConfigs,
|
|
305
|
+
{ createNew: true, walletId: identifier }
|
|
306
|
+
)
|
|
307
|
+
|
|
308
|
+
expect(mockSecureStorage.setEncryptionKey).toHaveBeenCalledWith(
|
|
309
|
+
expect.any(String),
|
|
310
|
+
identifier
|
|
311
|
+
)
|
|
312
|
+
})
|
|
313
|
+
|
|
314
|
+
it('should pass identifier when loading existing wallet', async () => {
|
|
315
|
+
const mockStore = getWorkletStore() as any
|
|
316
|
+
mockStore.getState = jest.fn(() => ({
|
|
317
|
+
isWorkletStarted: true,
|
|
318
|
+
isInitialized: false,
|
|
319
|
+
}))
|
|
320
|
+
|
|
321
|
+
// Ensure cache is clear
|
|
322
|
+
WalletSetupService.clearCredentialsCache()
|
|
323
|
+
|
|
324
|
+
const identifier = 'user@example.com'
|
|
325
|
+
await mockSecureStorage.setEncryptionKey('test-key', identifier)
|
|
326
|
+
await mockSecureStorage.setEncryptedSeed('test-seed', identifier)
|
|
327
|
+
|
|
328
|
+
await WalletSetupService.initializeWallet(
|
|
329
|
+
mockNetworkConfigs,
|
|
330
|
+
{ createNew: false, walletId: identifier }
|
|
331
|
+
)
|
|
332
|
+
|
|
333
|
+
expect(mockSecureStorage.getEncryptedSeed).toHaveBeenCalledWith(identifier)
|
|
334
|
+
expect(mockSecureStorage.getAllEncrypted).toHaveBeenCalledWith(identifier)
|
|
335
|
+
})
|
|
336
|
+
})
|
|
337
|
+
|
|
338
|
+
describe('Multi-wallet support with identifiers', () => {
|
|
339
|
+
it('should create different wallets for different identifiers', async () => {
|
|
340
|
+
// Mock generateEntropyAndEncrypt to return different values for different calls
|
|
341
|
+
let callCount = 0
|
|
342
|
+
const generateMock = WorkletLifecycleService.generateEntropyAndEncrypt as jest.Mock
|
|
343
|
+
generateMock.mockImplementation(() => {
|
|
344
|
+
callCount++
|
|
345
|
+
return Promise.resolve({
|
|
346
|
+
encryptionKey: `encryption-key-${callCount}`,
|
|
347
|
+
encryptedSeedBuffer: `encrypted-seed-${callCount}`,
|
|
348
|
+
encryptedEntropyBuffer: `encrypted-entropy-${callCount}`,
|
|
349
|
+
})
|
|
350
|
+
})
|
|
351
|
+
|
|
352
|
+
const identifier1 = 'user1@example.com'
|
|
353
|
+
const identifier2 = 'user2@example.com'
|
|
354
|
+
|
|
355
|
+
// Create wallet for user1
|
|
356
|
+
const result1 = await WalletSetupService.createNewWallet(
|
|
357
|
+
mockNetworkConfigs,
|
|
358
|
+
identifier1
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
// Create wallet for user2
|
|
362
|
+
const result2 = await WalletSetupService.createNewWallet(
|
|
363
|
+
mockNetworkConfigs,
|
|
364
|
+
identifier2
|
|
365
|
+
)
|
|
366
|
+
|
|
367
|
+
// Verify different seeds were generated
|
|
368
|
+
expect(result1.encryptedSeed).toBe('encrypted-seed-1')
|
|
369
|
+
expect(result2.encryptedSeed).toBe('encrypted-seed-2')
|
|
370
|
+
expect(result1.encryptedSeed).not.toBe(result2.encryptedSeed)
|
|
371
|
+
|
|
372
|
+
// Verify wallets are stored separately
|
|
373
|
+
expect(mockSecureStorage.setEncryptionKey).toHaveBeenCalledWith(
|
|
374
|
+
'encryption-key-1',
|
|
375
|
+
identifier1
|
|
376
|
+
)
|
|
377
|
+
expect(mockSecureStorage.setEncryptionKey).toHaveBeenCalledWith(
|
|
378
|
+
'encryption-key-2',
|
|
379
|
+
identifier2
|
|
380
|
+
)
|
|
381
|
+
|
|
382
|
+
// Verify we can load each wallet independently
|
|
383
|
+
const loaded1 = await WalletSetupService.loadExistingWallet(identifier1)
|
|
384
|
+
const loaded2 = await WalletSetupService.loadExistingWallet(identifier2)
|
|
385
|
+
|
|
386
|
+
expect(loaded1.encryptedSeed).toBe('encrypted-seed-1')
|
|
387
|
+
expect(loaded2.encryptedSeed).toBe('encrypted-seed-2')
|
|
388
|
+
expect(loaded1.encryptedSeed).not.toBe(loaded2.encryptedSeed)
|
|
389
|
+
})
|
|
390
|
+
|
|
391
|
+
it('should verify that creating two wallets with different identifiers gives different seeds', async () => {
|
|
392
|
+
// This is the specific test requested by the user
|
|
393
|
+
let seedCounter = 0
|
|
394
|
+
const generateMock = WorkletLifecycleService.generateEntropyAndEncrypt as jest.Mock
|
|
395
|
+
generateMock.mockImplementation(() => {
|
|
396
|
+
seedCounter++
|
|
397
|
+
// Simulate different entropy generation (in real scenario, this would be random)
|
|
398
|
+
return Promise.resolve({
|
|
399
|
+
encryptionKey: `key-${seedCounter}-${Date.now()}`,
|
|
400
|
+
encryptedSeedBuffer: `seed-${seedCounter}-${Math.random()}`,
|
|
401
|
+
encryptedEntropyBuffer: `entropy-${seedCounter}-${Math.random()}`,
|
|
402
|
+
})
|
|
403
|
+
})
|
|
404
|
+
|
|
405
|
+
const identifier1 = 'alice@example.com'
|
|
406
|
+
const identifier2 = 'bob@example.com'
|
|
407
|
+
|
|
408
|
+
const wallet1 = await WalletSetupService.createNewWallet(
|
|
409
|
+
mockNetworkConfigs,
|
|
410
|
+
identifier1
|
|
411
|
+
)
|
|
412
|
+
|
|
413
|
+
const wallet2 = await WalletSetupService.createNewWallet(
|
|
414
|
+
mockNetworkConfigs,
|
|
415
|
+
identifier2
|
|
416
|
+
)
|
|
417
|
+
|
|
418
|
+
// Critical assertion: seeds must be different
|
|
419
|
+
expect(wallet1.encryptedSeed).not.toBe(wallet2.encryptedSeed)
|
|
420
|
+
expect(wallet1.encryptionKey).not.toBe(wallet2.encryptionKey)
|
|
421
|
+
|
|
422
|
+
// Verify each wallet is stored with its own identifier
|
|
423
|
+
const hasWallet1 = await WalletSetupService.hasWallet(identifier1)
|
|
424
|
+
const hasWallet2 = await WalletSetupService.hasWallet(identifier2)
|
|
425
|
+
|
|
426
|
+
expect(hasWallet1).toBe(true)
|
|
427
|
+
expect(hasWallet2).toBe(true)
|
|
428
|
+
|
|
429
|
+
// Verify wallets are isolated - loading one doesn't affect the other
|
|
430
|
+
const loadedWallet1 = await WalletSetupService.loadExistingWallet(identifier1)
|
|
431
|
+
const loadedWallet2 = await WalletSetupService.loadExistingWallet(identifier2)
|
|
432
|
+
|
|
433
|
+
expect(loadedWallet1.encryptedSeed).toBe(wallet1.encryptedSeed)
|
|
434
|
+
expect(loadedWallet2.encryptedSeed).toBe(wallet2.encryptedSeed)
|
|
435
|
+
expect(loadedWallet1.encryptedSeed).not.toBe(loadedWallet2.encryptedSeed)
|
|
436
|
+
})
|
|
437
|
+
|
|
438
|
+
it('should isolate wallets by identifier', async () => {
|
|
439
|
+
const identifier1 = 'user1@example.com'
|
|
440
|
+
const identifier2 = 'user2@example.com'
|
|
441
|
+
|
|
442
|
+
// Create wallet for identifier1
|
|
443
|
+
await WalletSetupService.createNewWallet(
|
|
444
|
+
mockNetworkConfigs,
|
|
445
|
+
identifier1
|
|
446
|
+
)
|
|
447
|
+
|
|
448
|
+
// Create wallet for identifier2
|
|
449
|
+
await WalletSetupService.createNewWallet(
|
|
450
|
+
mockNetworkConfigs,
|
|
451
|
+
identifier2
|
|
452
|
+
)
|
|
453
|
+
|
|
454
|
+
// Verify each identifier has its own wallet
|
|
455
|
+
expect(await WalletSetupService.hasWallet(identifier1)).toBe(true)
|
|
456
|
+
expect(await WalletSetupService.hasWallet(identifier2)).toBe(true)
|
|
457
|
+
|
|
458
|
+
// Verify default identifier (no identifier) doesn't have a wallet
|
|
459
|
+
expect(await WalletSetupService.hasWallet(undefined)).toBe(false)
|
|
460
|
+
})
|
|
461
|
+
})
|
|
462
|
+
})
|
|
463
|
+
|