@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,411 @@
1
+ /**
2
+ * Tests for BalanceService
3
+ *
4
+ * Tests balance operations: getting, setting, updating, and managing balance state
5
+ */
6
+
7
+ import { BalanceService } from '../../services/balanceService'
8
+ import { getWalletStore } from '../../store/walletStore'
9
+
10
+ // Mock stores
11
+ jest.mock('../../store/walletStore', () => ({
12
+ getWalletStore: jest.fn(),
13
+ }))
14
+
15
+ describe('BalanceService', () => {
16
+ let mockWalletStore: any
17
+
18
+ beforeEach(() => {
19
+ jest.clearAllMocks()
20
+
21
+ // Setup mock wallet store
22
+ mockWalletStore = {
23
+ getState: jest.fn(() => ({
24
+ balances: {},
25
+ balanceLoading: {},
26
+ lastBalanceUpdate: {},
27
+ activeWalletId: 'test-wallet-1',
28
+ })),
29
+ setState: jest.fn(),
30
+ }
31
+
32
+ // Setup store mocks
33
+ ;(getWalletStore as jest.Mock).mockReturnValue(mockWalletStore)
34
+ })
35
+
36
+ describe('updateBalance', () => {
37
+ it('should update native balance', () => {
38
+ BalanceService.updateBalance(0, 'ethereum', null, '1000000000000000000')
39
+
40
+ expect(mockWalletStore.setState).toHaveBeenCalled()
41
+ const setStateCall = mockWalletStore.setState.mock.calls[0][0]
42
+ const prevState = { balances: {}, activeWalletId: 'test-wallet-1' }
43
+ const newState = setStateCall(prevState)
44
+
45
+ expect(newState.balances['test-wallet-1']?.ethereum?.[0]?.native).toBe('1000000000000000000')
46
+ })
47
+
48
+ it('should update token balance', () => {
49
+ BalanceService.updateBalance(
50
+ 0,
51
+ 'ethereum',
52
+ '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0',
53
+ '2000000000000000000'
54
+ )
55
+
56
+ expect(mockWalletStore.setState).toHaveBeenCalled()
57
+ const setStateCall = mockWalletStore.setState.mock.calls[0][0]
58
+ const prevState = { balances: {}, activeWalletId: 'test-wallet-1' }
59
+ const newState = setStateCall(prevState)
60
+
61
+ const tokenKey = '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0'
62
+ expect(newState.balances?.['test-wallet-1']?.ethereum?.[0]?.[tokenKey]).toBe(
63
+ '2000000000000000000'
64
+ )
65
+ })
66
+
67
+ it('should preserve existing balances', () => {
68
+ const prevState = {
69
+ balances: {
70
+ 'test-wallet-1': {
71
+ ethereum: {
72
+ 0: {
73
+ native: '1000000000000000000',
74
+ },
75
+ },
76
+ },
77
+ },
78
+ activeWalletId: 'test-wallet-1',
79
+ }
80
+
81
+ BalanceService.updateBalance(0, 'ethereum', '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0', '2000000000000000000')
82
+
83
+ const setStateCall = mockWalletStore.setState.mock.calls[0][0]
84
+ const newState = setStateCall(prevState)
85
+
86
+ expect(newState.balances['test-wallet-1']?.ethereum?.[0]?.native).toBe('1000000000000000000')
87
+ expect(newState.balances['test-wallet-1']?.ethereum?.[0]?.['0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0']).toBe(
88
+ '2000000000000000000'
89
+ )
90
+ })
91
+
92
+ it('should validate network name', () => {
93
+ expect(() => {
94
+ BalanceService.updateBalance(0, '', null, '100')
95
+ }).toThrow(/network.*non-empty|Network name must contain only|String must contain at least 1 character/)
96
+ })
97
+
98
+ it('should validate account index', () => {
99
+ expect(() => {
100
+ BalanceService.updateBalance(-1, 'ethereum', null, '100')
101
+ }).toThrow(/accountIndex.*non-negative|Number must be greater than or equal to 0/)
102
+ })
103
+
104
+ it('should validate balance', () => {
105
+ expect(() => {
106
+ BalanceService.updateBalance(0, 'ethereum', null, '')
107
+ }).toThrow(/balance.*valid number|Balance must be a valid number string/)
108
+ })
109
+ })
110
+
111
+ describe('getBalance', () => {
112
+ it('should get native balance', () => {
113
+ mockWalletStore.getState = jest.fn(() => ({
114
+ balances: {
115
+ 'test-wallet-1': {
116
+ ethereum: {
117
+ 0: {
118
+ native: '1000000000000000000',
119
+ },
120
+ },
121
+ },
122
+ },
123
+ activeWalletId: 'test-wallet-1',
124
+ }))
125
+
126
+ const balance = BalanceService.getBalance(0, 'ethereum', null)
127
+ expect(balance).toBe('1000000000000000000')
128
+ })
129
+
130
+ it('should get token balance', () => {
131
+ mockWalletStore.getState = jest.fn(() => ({
132
+ balances: {
133
+ 'test-wallet-1': {
134
+ ethereum: {
135
+ 0: {
136
+ native: '1000000000000000000',
137
+ '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0': '2000000000000000000',
138
+ },
139
+ },
140
+ },
141
+ },
142
+ activeWalletId: 'test-wallet-1',
143
+ }))
144
+
145
+ const balance = BalanceService.getBalance(0, 'ethereum', '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0')
146
+ expect(balance).toBe('2000000000000000000')
147
+ })
148
+
149
+ it('should return null if balance not found', () => {
150
+ mockWalletStore.getState = jest.fn(() => ({
151
+ balances: {},
152
+ activeWalletId: 'test-wallet-1',
153
+ }))
154
+
155
+ const balance = BalanceService.getBalance(0, 'ethereum', null)
156
+ expect(balance).toBe(null)
157
+ })
158
+
159
+ it('should validate network name', () => {
160
+ expect(() => {
161
+ BalanceService.getBalance(0, '', null)
162
+ }).toThrow(/network.*non-empty|Network name must contain only|String must contain at least 1 character/)
163
+ })
164
+
165
+ it('should validate account index', () => {
166
+ expect(() => {
167
+ BalanceService.getBalance(-1, 'ethereum', null)
168
+ }).toThrow(/accountIndex.*non-negative|Number must be greater than or equal to 0/)
169
+ })
170
+ })
171
+
172
+ describe('getBalancesForWallet', () => {
173
+ it('should get all balances for wallet', () => {
174
+ mockWalletStore.getState = jest.fn(() => ({
175
+ balances: {
176
+ 'test-wallet-1': {
177
+ ethereum: {
178
+ 0: {
179
+ native: '1000000000000000000',
180
+ '0x123': '2000000000000000000',
181
+ },
182
+ },
183
+ },
184
+ },
185
+ activeWalletId: 'test-wallet-1',
186
+ }))
187
+
188
+ const balances = BalanceService.getBalancesForWallet(0, 'ethereum')
189
+ expect(balances).toEqual({
190
+ native: '1000000000000000000',
191
+ '0x123': '2000000000000000000',
192
+ })
193
+ })
194
+
195
+ it('should return null if no balances found', () => {
196
+ mockWalletStore.getState = jest.fn(() => ({
197
+ balances: {},
198
+ activeWalletId: 'test-wallet-1',
199
+ }))
200
+
201
+ const balances = BalanceService.getBalancesForWallet(0, 'ethereum')
202
+ expect(balances).toBe(null)
203
+ })
204
+
205
+ it('should validate network name', () => {
206
+ expect(() => {
207
+ BalanceService.getBalancesForWallet(0, '')
208
+ }).toThrow(/network.*non-empty|Network name must contain only|String must contain at least 1 character/)
209
+ })
210
+
211
+ it('should validate account index', () => {
212
+ expect(() => {
213
+ BalanceService.getBalancesForWallet(-1, 'ethereum')
214
+ }).toThrow(/accountIndex.*non-negative|Number must be greater than or equal to 0/)
215
+ })
216
+ })
217
+
218
+ describe('setBalanceLoading', () => {
219
+ it('should set loading to true', () => {
220
+ BalanceService.setBalanceLoading('ethereum', 0, null, true)
221
+
222
+ expect(mockWalletStore.setState).toHaveBeenCalled()
223
+ const setStateCall = mockWalletStore.setState.mock.calls[0][0]
224
+ const prevState = { balanceLoading: {}, activeWalletId: 'test-wallet-1' }
225
+ const newState = setStateCall(prevState)
226
+
227
+ expect(newState.balanceLoading['test-wallet-1']?.['ethereum-0-native']).toBe(true)
228
+ })
229
+
230
+ it('should set loading to false', () => {
231
+ const prevState = {
232
+ balanceLoading: {
233
+ 'test-wallet-1': {
234
+ 'ethereum-0-native': true,
235
+ },
236
+ },
237
+ activeWalletId: 'test-wallet-1',
238
+ }
239
+
240
+ BalanceService.setBalanceLoading('ethereum', 0, null, false)
241
+
242
+ const setStateCall = mockWalletStore.setState.mock.calls[0][0]
243
+ const newState = setStateCall(prevState)
244
+
245
+ expect(newState.balanceLoading['test-wallet-1']?.['ethereum-0-native']).toBeUndefined()
246
+ })
247
+
248
+ it('should handle token loading state', () => {
249
+ BalanceService.setBalanceLoading('ethereum', 0, '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0', true)
250
+
251
+ const setStateCall = mockWalletStore.setState.mock.calls[0][0]
252
+ const prevState = { balanceLoading: {}, activeWalletId: 'test-wallet-1' }
253
+ const newState = setStateCall(prevState)
254
+
255
+ expect(newState.balanceLoading['test-wallet-1']?.['ethereum-0-0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0']).toBe(true)
256
+ })
257
+
258
+ it('should validate network name', () => {
259
+ expect(() => {
260
+ BalanceService.setBalanceLoading('', 0, null, true)
261
+ }).toThrow(/network.*non-empty|Network name must contain only|String must contain at least 1 character/)
262
+ })
263
+
264
+ it('should validate account index', () => {
265
+ expect(() => {
266
+ BalanceService.setBalanceLoading('ethereum', -1, null, true)
267
+ }).toThrow(/accountIndex.*non-negative|Number must be greater than or equal to 0/)
268
+ })
269
+ })
270
+
271
+ describe('isBalanceLoading', () => {
272
+ it('should return true if balance is loading', () => {
273
+ mockWalletStore.getState = jest.fn(() => ({
274
+ balanceLoading: {
275
+ 'test-wallet-1': {
276
+ 'ethereum-0-native': true,
277
+ },
278
+ },
279
+ activeWalletId: 'test-wallet-1',
280
+ }))
281
+
282
+ const isLoading = BalanceService.isBalanceLoading('ethereum', 0, null)
283
+ expect(isLoading).toBe(true)
284
+ })
285
+
286
+ it('should return false if balance is not loading', () => {
287
+ mockWalletStore.getState = jest.fn(() => ({
288
+ balanceLoading: {},
289
+ activeWalletId: 'test-wallet-1',
290
+ }))
291
+
292
+ const isLoading = BalanceService.isBalanceLoading('ethereum', 0, null)
293
+ expect(isLoading).toBe(false)
294
+ })
295
+
296
+ it('should validate network name', () => {
297
+ expect(() => {
298
+ BalanceService.isBalanceLoading('', 0, null)
299
+ }).toThrow(/network.*non-empty|Network name must contain only|String must contain at least 1 character/)
300
+ })
301
+
302
+ it('should validate account index', () => {
303
+ expect(() => {
304
+ BalanceService.isBalanceLoading('ethereum', -1, null)
305
+ }).toThrow(/accountIndex.*non-negative|Number must be greater than or equal to 0/)
306
+ })
307
+ })
308
+
309
+ describe('updateLastBalanceUpdate', () => {
310
+ it('should update last balance update timestamp', () => {
311
+ const beforeTime = Date.now()
312
+ BalanceService.updateLastBalanceUpdate('ethereum', 0)
313
+ const afterTime = Date.now()
314
+
315
+ expect(mockWalletStore.setState).toHaveBeenCalled()
316
+ const setStateCall = mockWalletStore.setState.mock.calls[0][0]
317
+ const prevState = { lastBalanceUpdate: {}, activeWalletId: 'test-wallet-1' }
318
+ const newState = setStateCall(prevState)
319
+
320
+ const timestamp = newState.lastBalanceUpdate['test-wallet-1']?.ethereum?.[0]
321
+ expect(timestamp).toBeGreaterThanOrEqual(beforeTime)
322
+ expect(timestamp).toBeLessThanOrEqual(afterTime)
323
+ })
324
+
325
+ it('should preserve existing timestamps', () => {
326
+ const prevState = {
327
+ lastBalanceUpdate: {
328
+ 'test-wallet-1': {
329
+ polygon: {
330
+ 0: 1234567890,
331
+ },
332
+ },
333
+ },
334
+ activeWalletId: 'test-wallet-1',
335
+ }
336
+
337
+ BalanceService.updateLastBalanceUpdate('ethereum', 0)
338
+
339
+ const setStateCall = mockWalletStore.setState.mock.calls[0][0]
340
+ const newState = setStateCall(prevState)
341
+
342
+ expect(newState.lastBalanceUpdate['test-wallet-1']?.polygon?.[0]).toBe(1234567890)
343
+ expect(newState.lastBalanceUpdate['test-wallet-1']?.ethereum?.[0]).toBeDefined()
344
+ })
345
+
346
+ it('should validate network name', () => {
347
+ expect(() => {
348
+ BalanceService.updateLastBalanceUpdate('', 0)
349
+ }).toThrow(/network.*non-empty|Network name must contain only|String must contain at least 1 character/)
350
+ })
351
+
352
+ it('should validate account index', () => {
353
+ expect(() => {
354
+ BalanceService.updateLastBalanceUpdate('ethereum', -1)
355
+ }).toThrow(/accountIndex.*non-negative|Number must be greater than or equal to 0/)
356
+ })
357
+ })
358
+
359
+ describe('getLastBalanceUpdate', () => {
360
+ it('should get last balance update timestamp', () => {
361
+ const timestamp = 1234567890
362
+ mockWalletStore.getState = jest.fn(() => ({
363
+ lastBalanceUpdate: {
364
+ 'test-wallet-1': {
365
+ ethereum: {
366
+ 0: timestamp,
367
+ },
368
+ },
369
+ },
370
+ activeWalletId: 'test-wallet-1',
371
+ }))
372
+
373
+ const result = BalanceService.getLastBalanceUpdate('ethereum', 0)
374
+ expect(result).toBe(timestamp)
375
+ })
376
+
377
+ it('should return null if timestamp not found', () => {
378
+ mockWalletStore.getState = jest.fn(() => ({
379
+ lastBalanceUpdate: {},
380
+ }))
381
+
382
+ const result = BalanceService.getLastBalanceUpdate('ethereum', 0)
383
+ expect(result).toBe(null)
384
+ })
385
+
386
+ it('should validate network name', () => {
387
+ expect(() => {
388
+ BalanceService.getLastBalanceUpdate('', 0)
389
+ }).toThrow(/network.*non-empty|Network name must contain only|String must contain at least 1 character/)
390
+ })
391
+
392
+ it('should validate account index', () => {
393
+ expect(() => {
394
+ BalanceService.getLastBalanceUpdate('ethereum', -1)
395
+ }).toThrow(/accountIndex.*non-negative|Number must be greater than or equal to 0/)
396
+ })
397
+ })
398
+
399
+ describe('clearBalances', () => {
400
+ it('should clear all balances', () => {
401
+ BalanceService.clearBalances()
402
+
403
+ expect(mockWalletStore.setState).toHaveBeenCalledWith({
404
+ balances: {},
405
+ balanceLoading: {},
406
+ lastBalanceUpdate: {},
407
+ })
408
+ })
409
+ })
410
+ })
411
+