@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.
Files changed (275) hide show
  1. package/README.md +551 -0
  2. package/dist/__mocks__/react.d.ts +40 -0
  3. package/dist/__mocks__/react.js +33 -0
  4. package/dist/__mocks__/react.js.map +1 -0
  5. package/dist/__mocks__/secureStorage.d.ts +26 -0
  6. package/dist/__mocks__/secureStorage.js +80 -0
  7. package/dist/__mocks__/secureStorage.js.map +1 -0
  8. package/dist/__tests__/hooks/useBalance.test.d.ts +6 -0
  9. package/dist/__tests__/hooks/useBalance.test.js +217 -0
  10. package/dist/__tests__/hooks/useBalance.test.js.map +1 -0
  11. package/dist/__tests__/hooks/useWallet.test.d.ts +6 -0
  12. package/dist/__tests__/hooks/useWallet.test.js +105 -0
  13. package/dist/__tests__/hooks/useWallet.test.js.map +1 -0
  14. package/dist/__tests__/hooks/useWalletManager.test.d.ts +6 -0
  15. package/dist/__tests__/hooks/useWalletManager.test.js +193 -0
  16. package/dist/__tests__/hooks/useWalletManager.test.js.map +1 -0
  17. package/dist/__tests__/hooks/useWdkApp.test.d.ts +6 -0
  18. package/dist/__tests__/hooks/useWdkApp.test.js +55 -0
  19. package/dist/__tests__/hooks/useWdkApp.test.js.map +1 -0
  20. package/dist/__tests__/hooks/useWorklet.test.d.ts +6 -0
  21. package/dist/__tests__/hooks/useWorklet.test.js +168 -0
  22. package/dist/__tests__/hooks/useWorklet.test.js.map +1 -0
  23. package/dist/__tests__/provider/WdkAppProvider.test.d.ts +6 -0
  24. package/dist/__tests__/provider/WdkAppProvider.test.js +57 -0
  25. package/dist/__tests__/provider/WdkAppProvider.test.js.map +1 -0
  26. package/dist/__tests__/services/accountService.test.d.ts +6 -0
  27. package/dist/__tests__/services/accountService.test.js +216 -0
  28. package/dist/__tests__/services/accountService.test.js.map +1 -0
  29. package/dist/__tests__/services/addressService.test.d.ts +6 -0
  30. package/dist/__tests__/services/addressService.test.js +246 -0
  31. package/dist/__tests__/services/addressService.test.js.map +1 -0
  32. package/dist/__tests__/services/balanceService.test.d.ts +6 -0
  33. package/dist/__tests__/services/balanceService.test.js +333 -0
  34. package/dist/__tests__/services/balanceService.test.js.map +1 -0
  35. package/dist/__tests__/services/walletSetupService.test.d.ts +6 -0
  36. package/dist/__tests__/services/walletSetupService.test.js +304 -0
  37. package/dist/__tests__/services/walletSetupService.test.js.map +1 -0
  38. package/dist/__tests__/services/walletSwitchingService.test.d.ts +6 -0
  39. package/dist/__tests__/services/walletSwitchingService.test.js +209 -0
  40. package/dist/__tests__/services/walletSwitchingService.test.js.map +1 -0
  41. package/dist/__tests__/services/workletLifecycleService.test.d.ts +6 -0
  42. package/dist/__tests__/services/workletLifecycleService.test.js +451 -0
  43. package/dist/__tests__/services/workletLifecycleService.test.js.map +1 -0
  44. package/dist/__tests__/setup.d.ts +7 -0
  45. package/dist/__tests__/setup.js +49 -0
  46. package/dist/__tests__/setup.js.map +1 -0
  47. package/dist/__tests__/storage/mmkvStorage.test.d.ts +6 -0
  48. package/dist/__tests__/storage/mmkvStorage.test.js +213 -0
  49. package/dist/__tests__/storage/mmkvStorage.test.js.map +1 -0
  50. package/dist/__tests__/store/walletStore.test.d.ts +4 -0
  51. package/dist/__tests__/store/walletStore.test.js +86 -0
  52. package/dist/__tests__/store/walletStore.test.js.map +1 -0
  53. package/dist/__tests__/store/workletStore.test.d.ts +4 -0
  54. package/dist/__tests__/store/workletStore.test.js +255 -0
  55. package/dist/__tests__/store/workletStore.test.js.map +1 -0
  56. package/dist/__tests__/types/hrpc.test.d.ts +4 -0
  57. package/dist/__tests__/types/hrpc.test.js +99 -0
  58. package/dist/__tests__/types/hrpc.test.js.map +1 -0
  59. package/dist/__tests__/utils/balanceUtils.test.d.ts +4 -0
  60. package/dist/__tests__/utils/balanceUtils.test.js +133 -0
  61. package/dist/__tests__/utils/balanceUtils.test.js.map +1 -0
  62. package/dist/__tests__/utils/errorHandling.test.d.ts +6 -0
  63. package/dist/__tests__/utils/errorHandling.test.js +119 -0
  64. package/dist/__tests__/utils/errorHandling.test.js.map +1 -0
  65. package/dist/__tests__/utils/errorUtils.test.d.ts +4 -0
  66. package/dist/__tests__/utils/errorUtils.test.js +133 -0
  67. package/dist/__tests__/utils/errorUtils.test.js.map +1 -0
  68. package/dist/__tests__/utils/initializationState.test.d.ts +6 -0
  69. package/dist/__tests__/utils/initializationState.test.js +243 -0
  70. package/dist/__tests__/utils/initializationState.test.js.map +1 -0
  71. package/dist/__tests__/utils/jsonUtils.test.d.ts +4 -0
  72. package/dist/__tests__/utils/jsonUtils.test.js +118 -0
  73. package/dist/__tests__/utils/jsonUtils.test.js.map +1 -0
  74. package/dist/__tests__/utils/mmkvKeyManager.test.d.ts +6 -0
  75. package/dist/__tests__/utils/mmkvKeyManager.test.js +158 -0
  76. package/dist/__tests__/utils/mmkvKeyManager.test.js.map +1 -0
  77. package/dist/__tests__/utils/mnemonicUtils.test.d.ts +4 -0
  78. package/dist/__tests__/utils/mnemonicUtils.test.js +40 -0
  79. package/dist/__tests__/utils/mnemonicUtils.test.js.map +1 -0
  80. package/dist/__tests__/utils/raceConditions.test.d.ts +6 -0
  81. package/dist/__tests__/utils/raceConditions.test.js +239 -0
  82. package/dist/__tests__/utils/raceConditions.test.js.map +1 -0
  83. package/dist/__tests__/utils/result.test.d.ts +4 -0
  84. package/dist/__tests__/utils/result.test.js +66 -0
  85. package/dist/__tests__/utils/result.test.js.map +1 -0
  86. package/dist/__tests__/utils/schemas.test.d.ts +4 -0
  87. package/dist/__tests__/utils/schemas.test.js +66 -0
  88. package/dist/__tests__/utils/schemas.test.js.map +1 -0
  89. package/dist/__tests__/utils/storeHelpers.test.d.ts +4 -0
  90. package/dist/__tests__/utils/storeHelpers.test.js +227 -0
  91. package/dist/__tests__/utils/storeHelpers.test.js.map +1 -0
  92. package/dist/__tests__/utils/typeGuards.test.d.ts +4 -0
  93. package/dist/__tests__/utils/typeGuards.test.js +175 -0
  94. package/dist/__tests__/utils/typeGuards.test.js.map +1 -0
  95. package/dist/__tests__/utils/validation.test.d.ts +4 -0
  96. package/dist/__tests__/utils/validation.test.js +126 -0
  97. package/dist/__tests__/utils/validation.test.js.map +1 -0
  98. package/dist/__tests__/utils/walletUtils.test.d.ts +4 -0
  99. package/dist/__tests__/utils/walletUtils.test.js +156 -0
  100. package/dist/__tests__/utils/walletUtils.test.js.map +1 -0
  101. package/dist/hooks/useBalance.d.ts +170 -0
  102. package/dist/hooks/useBalance.js +442 -0
  103. package/dist/hooks/useBalance.js.map +1 -0
  104. package/dist/hooks/useWallet.d.ts +43 -0
  105. package/dist/hooks/useWallet.js +193 -0
  106. package/dist/hooks/useWallet.js.map +1 -0
  107. package/dist/hooks/useWalletManager.d.ts +100 -0
  108. package/dist/hooks/useWalletManager.js +526 -0
  109. package/dist/hooks/useWalletManager.js.map +1 -0
  110. package/dist/hooks/useWdkApp.d.ts +66 -0
  111. package/dist/hooks/useWdkApp.js +74 -0
  112. package/dist/hooks/useWdkApp.js.map +1 -0
  113. package/dist/hooks/useWorklet.d.ts +66 -0
  114. package/dist/hooks/useWorklet.js +42 -0
  115. package/dist/hooks/useWorklet.js.map +1 -0
  116. package/dist/index.d.ts +33 -0
  117. package/dist/index.js +36 -0
  118. package/dist/index.js.map +1 -0
  119. package/dist/provider/WdkAppProvider.d.ts +112 -0
  120. package/dist/provider/WdkAppProvider.js +558 -0
  121. package/dist/provider/WdkAppProvider.js.map +1 -0
  122. package/dist/services/accountService.d.ts +52 -0
  123. package/dist/services/accountService.js +119 -0
  124. package/dist/services/accountService.js.map +1 -0
  125. package/dist/services/addressService.d.ts +22 -0
  126. package/dist/services/addressService.js +110 -0
  127. package/dist/services/addressService.js.map +1 -0
  128. package/dist/services/balanceService.d.ts +114 -0
  129. package/dist/services/balanceService.js +208 -0
  130. package/dist/services/balanceService.js.map +1 -0
  131. package/dist/services/walletSetupService.d.ts +217 -0
  132. package/dist/services/walletSetupService.js +535 -0
  133. package/dist/services/walletSetupService.js.map +1 -0
  134. package/dist/services/walletSwitchingService.d.ts +48 -0
  135. package/dist/services/walletSwitchingService.js +143 -0
  136. package/dist/services/walletSwitchingService.js.map +1 -0
  137. package/dist/services/workletLifecycleService.d.ts +117 -0
  138. package/dist/services/workletLifecycleService.js +433 -0
  139. package/dist/services/workletLifecycleService.js.map +1 -0
  140. package/dist/storage/mmkvStorage.d.ts +44 -0
  141. package/dist/storage/mmkvStorage.js +348 -0
  142. package/dist/storage/mmkvStorage.js.map +1 -0
  143. package/dist/store/walletStore.d.ts +130 -0
  144. package/dist/store/walletStore.js +204 -0
  145. package/dist/store/walletStore.js.map +1 -0
  146. package/dist/store/workletStore.d.ts +121 -0
  147. package/dist/store/workletStore.js +256 -0
  148. package/dist/store/workletStore.js.map +1 -0
  149. package/dist/types/hrpc.d.ts +60 -0
  150. package/dist/types/hrpc.js +26 -0
  151. package/dist/types/hrpc.js.map +1 -0
  152. package/dist/types.d.ts +168 -0
  153. package/dist/types.js +7 -0
  154. package/dist/types.js.map +1 -0
  155. package/dist/utils/balanceUtils.d.ts +30 -0
  156. package/dist/utils/balanceUtils.js +86 -0
  157. package/dist/utils/balanceUtils.js.map +1 -0
  158. package/dist/utils/constants.d.ts +66 -0
  159. package/dist/utils/constants.js +73 -0
  160. package/dist/utils/constants.js.map +1 -0
  161. package/dist/utils/errorHandling.d.ts +47 -0
  162. package/dist/utils/errorHandling.js +54 -0
  163. package/dist/utils/errorHandling.js.map +1 -0
  164. package/dist/utils/errorUtils.d.ts +89 -0
  165. package/dist/utils/errorUtils.js +264 -0
  166. package/dist/utils/errorUtils.js.map +1 -0
  167. package/dist/utils/initializationState.d.ts +129 -0
  168. package/dist/utils/initializationState.js +220 -0
  169. package/dist/utils/initializationState.js.map +1 -0
  170. package/dist/utils/jsonUtils.d.ts +21 -0
  171. package/dist/utils/jsonUtils.js +67 -0
  172. package/dist/utils/jsonUtils.js.map +1 -0
  173. package/dist/utils/logger.d.ts +27 -0
  174. package/dist/utils/logger.js +50 -0
  175. package/dist/utils/logger.js.map +1 -0
  176. package/dist/utils/mmkvKeyManager.d.ts +57 -0
  177. package/dist/utils/mmkvKeyManager.js +214 -0
  178. package/dist/utils/mmkvKeyManager.js.map +1 -0
  179. package/dist/utils/mnemonicUtils.d.ts +17 -0
  180. package/dist/utils/mnemonicUtils.js +28 -0
  181. package/dist/utils/mnemonicUtils.js.map +1 -0
  182. package/dist/utils/operationMutex.d.ts +69 -0
  183. package/dist/utils/operationMutex.js +150 -0
  184. package/dist/utils/operationMutex.js.map +1 -0
  185. package/dist/utils/result.d.ts +34 -0
  186. package/dist/utils/result.js +43 -0
  187. package/dist/utils/result.js.map +1 -0
  188. package/dist/utils/schemas.d.ts +365 -0
  189. package/dist/utils/schemas.js +152 -0
  190. package/dist/utils/schemas.js.map +1 -0
  191. package/dist/utils/storeHelpers.d.ts +112 -0
  192. package/dist/utils/storeHelpers.js +198 -0
  193. package/dist/utils/storeHelpers.js.map +1 -0
  194. package/dist/utils/typeGuards.d.ts +70 -0
  195. package/dist/utils/typeGuards.js +95 -0
  196. package/dist/utils/typeGuards.js.map +1 -0
  197. package/dist/utils/validation.d.ts +53 -0
  198. package/dist/utils/validation.js +152 -0
  199. package/dist/utils/validation.js.map +1 -0
  200. package/dist/utils/walletStateHelpers.d.ts +62 -0
  201. package/dist/utils/walletStateHelpers.js +81 -0
  202. package/dist/utils/walletStateHelpers.js.map +1 -0
  203. package/dist/utils/walletUtils.d.ts +38 -0
  204. package/dist/utils/walletUtils.js +87 -0
  205. package/dist/utils/walletUtils.js.map +1 -0
  206. package/package.json +79 -0
  207. package/src/__mocks__/react.ts +34 -0
  208. package/src/__mocks__/secureStorage.ts +87 -0
  209. package/src/__tests__/hooks/useBalance.test.ts +286 -0
  210. package/src/__tests__/hooks/useWallet.test.ts +122 -0
  211. package/src/__tests__/hooks/useWalletManager.test.ts +271 -0
  212. package/src/__tests__/hooks/useWdkApp.test.tsx +59 -0
  213. package/src/__tests__/hooks/useWorklet.test.ts +195 -0
  214. package/src/__tests__/provider/WdkAppProvider.test.tsx +67 -0
  215. package/src/__tests__/services/accountService.test.ts +337 -0
  216. package/src/__tests__/services/addressService.test.ts +312 -0
  217. package/src/__tests__/services/balanceService.test.ts +411 -0
  218. package/src/__tests__/services/walletSetupService.test.ts +463 -0
  219. package/src/__tests__/services/walletSwitchingService.test.ts +258 -0
  220. package/src/__tests__/services/workletLifecycleService.test.ts +514 -0
  221. package/src/__tests__/setup.ts +54 -0
  222. package/src/__tests__/storage/mmkvStorage.test.ts +325 -0
  223. package/src/__tests__/store/walletStore.test.ts +101 -0
  224. package/src/__tests__/store/workletStore.test.ts +329 -0
  225. package/src/__tests__/types/hrpc.test.ts +125 -0
  226. package/src/__tests__/utils/balanceUtils.test.ts +151 -0
  227. package/src/__tests__/utils/errorHandling.test.ts +147 -0
  228. package/src/__tests__/utils/errorUtils.test.ts +170 -0
  229. package/src/__tests__/utils/initializationState.test.ts +337 -0
  230. package/src/__tests__/utils/jsonUtils.test.ts +131 -0
  231. package/src/__tests__/utils/mmkvKeyManager.test.ts +205 -0
  232. package/src/__tests__/utils/mnemonicUtils.test.ts +48 -0
  233. package/src/__tests__/utils/raceConditions.test.ts +292 -0
  234. package/src/__tests__/utils/result.test.ts +73 -0
  235. package/src/__tests__/utils/schemas.test.ts +82 -0
  236. package/src/__tests__/utils/storeHelpers.test.ts +323 -0
  237. package/src/__tests__/utils/typeGuards.test.ts +209 -0
  238. package/src/__tests__/utils/validation.test.ts +152 -0
  239. package/src/__tests__/utils/walletUtils.test.ts +195 -0
  240. package/src/hooks/useBalance.ts +597 -0
  241. package/src/hooks/useWallet.ts +288 -0
  242. package/src/hooks/useWalletManager.ts +654 -0
  243. package/src/hooks/useWdkApp.ts +78 -0
  244. package/src/hooks/useWorklet.ts +109 -0
  245. package/src/index.ts +112 -0
  246. package/src/provider/WdkAppProvider.tsx +764 -0
  247. package/src/services/accountService.ts +134 -0
  248. package/src/services/addressService.ts +125 -0
  249. package/src/services/balanceService.ts +291 -0
  250. package/src/services/walletSetupService.ts +695 -0
  251. package/src/services/walletSwitchingService.ts +157 -0
  252. package/src/services/workletLifecycleService.ts +561 -0
  253. package/src/storage/mmkvStorage.ts +417 -0
  254. package/src/store/walletStore.ts +301 -0
  255. package/src/store/workletStore.ts +340 -0
  256. package/src/types/hrpc.ts +78 -0
  257. package/src/types.ts +188 -0
  258. package/src/utils/balanceUtils.ts +96 -0
  259. package/src/utils/constants.ts +84 -0
  260. package/src/utils/errorHandling.md +163 -0
  261. package/src/utils/errorHandling.ts +61 -0
  262. package/src/utils/errorUtils.ts +300 -0
  263. package/src/utils/initializationState.ts +242 -0
  264. package/src/utils/jsonUtils.ts +75 -0
  265. package/src/utils/logger.ts +54 -0
  266. package/src/utils/mmkvKeyManager.ts +256 -0
  267. package/src/utils/mnemonicUtils.ts +35 -0
  268. package/src/utils/operationMutex.ts +181 -0
  269. package/src/utils/result.ts +57 -0
  270. package/src/utils/schemas.ts +190 -0
  271. package/src/utils/storeHelpers.ts +236 -0
  272. package/src/utils/typeGuards.ts +129 -0
  273. package/src/utils/validation.ts +174 -0
  274. package/src/utils/walletStateHelpers.ts +104 -0
  275. 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
+