@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
package/README.md ADDED
@@ -0,0 +1,551 @@
1
+ # @spacesops/wdk-react-native-core
2
+
3
+ Core functionality for React Native wallets - wallet management, balance fetching, and worklet operations.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Quick Start](#quick-start)
8
+ - [Installation](#installation)
9
+ - [Core Concepts](#core-concepts)
10
+ - [Usage Examples](#usage-examples)
11
+ - [API Reference](#api-reference)
12
+ - [Architecture](#architecture)
13
+ - [Security](#security)
14
+ - [Troubleshooting](#troubleshooting)
15
+ - [Development](#development)
16
+
17
+ ## Quick Start
18
+
19
+ ```typescript
20
+ import { WdkAppProvider, useWdkApp, useWallet, useBalance } from '@spacesops/wdk-react-native-core'
21
+ import { createSecureStorage } from '@tetherto/wdk-react-native-secure-storage'
22
+
23
+ function App() {
24
+ const secureStorage = createSecureStorage()
25
+ const networkConfigs = {
26
+ ethereum: { chainId: 1, blockchain: 'ethereum' }
27
+ }
28
+ const tokenConfigs = {
29
+ ethereum: {
30
+ native: { address: null, symbol: 'ETH', name: 'Ethereum', decimals: 18 },
31
+ tokens: []
32
+ }
33
+ }
34
+
35
+ return (
36
+ <WdkAppProvider
37
+ networkConfigs={networkConfigs}
38
+ tokenConfigs={tokenConfigs}
39
+ >
40
+ <WalletScreen />
41
+ </WdkAppProvider>
42
+ )
43
+ }
44
+
45
+ function WalletScreen() {
46
+ const { status, isReady } = useWdkApp()
47
+ const { addresses } = useWallet()
48
+ const { data: balance, isLoading } = useBalance({
49
+ network: 'ethereum',
50
+ accountIndex: 0,
51
+ tokenAddress: null
52
+ })
53
+
54
+ if (!isReady) return <Text>Loading...</Text>
55
+
56
+ return (
57
+ <View>
58
+ <Text>Address: {addresses.ethereum?.[0]}</Text>
59
+ <Text>Balance: {balance || '0'}</Text>
60
+ {isLoading && <Text>Updating...</Text>}
61
+ </View>
62
+ )
63
+ }
64
+ ```
65
+
66
+ ## Installation
67
+
68
+ ### Step 1: Install Dependencies
69
+
70
+ This package is part of the **Spacesops beta.40 pipeline**. Install matching peer/runtime versions in your host app:
71
+
72
+ ```bash
73
+ npm install @spacesops/wdk-react-native-core@1.0.0-beta.40
74
+ npm install @spacesops/pear-wrk-wdk@1.1.1-beta.40 @spacesops/react-native-bare-kit@0.11.0-beta.40
75
+ npm install @tetherto/wdk-react-native-secure-storage
76
+ npm install react@">=18.0.0" react-native@">=0.70.0"
77
+ ```
78
+
79
+ **Host app notes (beta.40):**
80
+
81
+ - You do **not** need `wire-worklet.js`, `relink-bare-addons.js`, or a direct `@spacesops/wdk-wallet-btc` dependency—bitcoin runs inside the pear worklet bundle.
82
+ - On **Android**, configure **`keepDebugSymbols`** for `libbare*.so` in your Expo app or config plugin (see `@spacesops/react-native-bare-kit` README).
83
+ - Include **`bitcoin`** in `networkConfigs` (electrum URLs, etc.) so it matches pear’s `networks: ["bitcoin"]`.
84
+
85
+ ### Step 2: Install from GitHub (if using source)
86
+
87
+ ```bash
88
+ npm install https://github.com/spacesops/wdk-react-native-core.git
89
+ ```
90
+
91
+ Or add to your `package.json`:
92
+
93
+ ```json
94
+ {
95
+ "dependencies": {
96
+ "@spacesops/wdk-react-native-core": "1.0.0-beta.40",
97
+ "@spacesops/pear-wrk-wdk": "1.1.1-beta.40",
98
+ "@spacesops/react-native-bare-kit": "0.11.0-beta.40",
99
+ "@tetherto/wdk-react-native-secure-storage": "github:tetherto/wdk-react-native-secure-storage"
100
+ }
101
+ }
102
+ ```
103
+
104
+ ## Core Concepts
105
+
106
+ ### WdkAppProvider
107
+
108
+ The root provider that manages wallet initialization and worklet lifecycle. Wrap your app with it:
109
+
110
+ ```typescript
111
+ <WdkAppProvider
112
+ networkConfigs={networkConfigs}
113
+ tokenConfigs={tokenConfigs}
114
+ >
115
+ {children}
116
+ </WdkAppProvider>
117
+ ```
118
+
119
+ ### Hooks
120
+
121
+ - **`useWdkApp()`** - App-level initialization state (is app ready? what's the status?)
122
+ - **`useWallet()`** - Wallet operations (addresses, account methods) - use AFTER initialization
123
+ - **`useBalance()`** - Fetch and manage balances (uses TanStack Query)
124
+ - **`useWalletManager()`** - Wallet lifecycle (create, load, import, delete) - use BEFORE operations
125
+ - **`useWorklet()`** - Worklet state and operations (advanced use cases)
126
+
127
+ ## Which Hook Should I Use?
128
+
129
+ ### App Initialization State
130
+ Use `useWdkApp()` to check if the app is ready:
131
+ ```typescript
132
+ const { status, isReady, error } = useWdkApp()
133
+ if (!isReady) return <LoadingScreen />
134
+ ```
135
+
136
+ ### Wallet Lifecycle (Create, Load, Import, Delete)
137
+ Use `useWalletManager()` for wallet setup - this is the ONLY hook for wallet lifecycle:
138
+ ```typescript
139
+ const { createWallet, loadWallet, importWallet, hasWallet, deleteWallet } = useWalletManager(networkConfigs)
140
+ ```
141
+
142
+ ### Wallet Operations (After Initialization)
143
+ Use `useWallet()` for wallet data and operations:
144
+ ```typescript
145
+ const { addresses, getAddress, callAccountMethod } = useWallet()
146
+ ```
147
+
148
+ ### Balance Fetching
149
+ Use `useBalance()` for balances:
150
+ ```typescript
151
+ const { data: balance, isLoading } = useBalance({
152
+ network: 'ethereum',
153
+ accountIndex: 0,
154
+ tokenAddress: null
155
+ })
156
+ ```
157
+
158
+ ### State Management
159
+
160
+ - **Zustand Stores**: `workletStore` (worklet lifecycle), `walletStore` (wallet data)
161
+ - **TanStack Query**: Balance fetching with automatic caching and refetching
162
+ - **React State**: Component-level state via hooks
163
+
164
+ ## Usage Examples
165
+
166
+ ### Basic Wallet Setup
167
+
168
+ ```typescript
169
+ import { WdkAppProvider, useWdkApp, useWalletManager } from '@spacesops/wdk-react-native-core'
170
+
171
+ function App() {
172
+ return (
173
+ <WdkAppProvider networkConfigs={networkConfigs} tokenConfigs={tokenConfigs}>
174
+ <WalletSetup />
175
+ </WdkAppProvider>
176
+ )
177
+ }
178
+
179
+ function WalletSetup() {
180
+ const { status, isReady } = useWdkApp()
181
+ const { createWallet, loadWallet, hasWallet } = useWalletManager()
182
+
183
+ useEffect(() => {
184
+ const init = async () => {
185
+ const exists = await hasWallet()
186
+ if (exists) {
187
+ await loadWallet()
188
+ } else {
189
+ await createWallet()
190
+ }
191
+ }
192
+ if (isReady) init()
193
+ }, [isReady])
194
+
195
+ if (!isReady) return <LoadingScreen />
196
+
197
+ return <WalletApp />
198
+ }
199
+ ```
200
+
201
+ ### Fetching Balances
202
+
203
+ ```typescript
204
+ import { useBalance, useBalancesForWallet } from '@spacesops/wdk-react-native-core'
205
+
206
+ function BalanceDisplay() {
207
+ // Single balance
208
+ const { data: balance, isLoading, error } = useBalance({
209
+ network: 'ethereum',
210
+ accountIndex: 0,
211
+ tokenAddress: null // null for native token
212
+ })
213
+
214
+ // All balances for a wallet
215
+ const { data: allBalances } = useBalancesForWallet({
216
+ accountIndex: 0,
217
+ networks: ['ethereum', 'spark']
218
+ })
219
+
220
+ return (
221
+ <View>
222
+ <Text>ETH Balance: {balance || '0'}</Text>
223
+ {isLoading && <Text>Loading...</Text>}
224
+ {error && <Text>Error: {error.message}</Text>}
225
+ </View>
226
+ )
227
+ }
228
+ ```
229
+
230
+ ### Using Account Methods
231
+
232
+ ```typescript
233
+ import { useWallet } from '@spacesops/wdk-react-native-core'
234
+
235
+ function AccountOperations() {
236
+ const { callAccountMethod, isInitialized } = useWallet()
237
+
238
+ const handleGetBalance = async () => {
239
+ try {
240
+ const balance = await callAccountMethod(
241
+ 'ethereum',
242
+ 0,
243
+ 'getBalance',
244
+ null
245
+ )
246
+ console.log('Balance:', balance)
247
+ } catch (error) {
248
+ console.error('Failed:', error)
249
+ }
250
+ }
251
+
252
+ const handleSignMessage = async (message: string) => {
253
+ try {
254
+ const signature = await callAccountMethod(
255
+ 'ethereum',
256
+ 0,
257
+ 'signMessage',
258
+ { message }
259
+ )
260
+ console.log('Signature:', signature)
261
+ } catch (error) {
262
+ console.error('Failed:', error)
263
+ }
264
+ }
265
+
266
+ if (!isInitialized) return <Text>Not initialized</Text>
267
+
268
+ return (
269
+ <View>
270
+ <Button onPress={handleGetBalance}>Get Balance</Button>
271
+ <Button onPress={() => handleSignMessage('Hello')}>Sign Message</Button>
272
+ </View>
273
+ )
274
+ }
275
+ ```
276
+
277
+ ### Multiple Wallets
278
+
279
+ ```typescript
280
+ import { useWallet } from '@spacesops/wdk-react-native-core'
281
+
282
+ function MultiWalletApp() {
283
+ const wallet1 = useWallet({ identifier: 'wallet-1' })
284
+ const wallet2 = useWallet({ identifier: 'wallet-2' })
285
+
286
+ return (
287
+ <View>
288
+ <Text>Wallet 1: {wallet1.addresses.ethereum?.[0]}</Text>
289
+ <Text>Wallet 2: {wallet2.addresses.ethereum?.[0]}</Text>
290
+ </View>
291
+ )
292
+ }
293
+ ```
294
+
295
+ ### Refreshing Balances
296
+
297
+ ```typescript
298
+ import { useRefreshBalance } from '@spacesops/wdk-react-native-core'
299
+
300
+ function RefreshButton() {
301
+ const { mutate: refreshBalance } = useRefreshBalance()
302
+
303
+ const handleRefresh = () => {
304
+ refreshBalance({
305
+ network: 'ethereum',
306
+ accountIndex: 0,
307
+ tokenAddress: null
308
+ })
309
+ }
310
+
311
+ return <Button onPress={handleRefresh}>Refresh Balance</Button>
312
+ }
313
+ ```
314
+
315
+ ## API Reference
316
+
317
+ ### WdkAppProvider
318
+
319
+ ```typescript
320
+ interface WdkAppProviderProps {
321
+ networkConfigs: NetworkConfigs
322
+ tokenConfigs: TokenConfigs
323
+ children: React.ReactNode
324
+ }
325
+ ```
326
+
327
+ ### useWdkApp()
328
+
329
+ App-level initialization state. Use this to check if the app is ready.
330
+
331
+ ```typescript
332
+ interface WdkAppContextValue {
333
+ status: AppStatus
334
+ isInitializing: boolean
335
+ isReady: boolean
336
+ workletStatus: InitializationStatus
337
+ workletState: { isReady: boolean; isLoading: boolean; error: string | null }
338
+ walletState: { status: string; identifier: string | null; error: Error | null }
339
+ activeWalletId: string | null
340
+ loadingWalletId: string | null
341
+ walletExists: boolean | null
342
+ error: Error | null
343
+ retry: () => void
344
+ // Note: Wallet lifecycle operations (create, load, import, delete) are available via useWalletManager()
345
+ }
346
+ ```
347
+
348
+ ### useWallet()
349
+
350
+ ```typescript
351
+ interface UseWalletResult {
352
+ addresses: WalletAddresses
353
+ isInitialized: boolean
354
+ isSwitchingWallet: boolean
355
+ switchWalletError: Error | null
356
+ isTemporaryWallet: boolean
357
+ getAddress: (network: string, accountIndex: number) => Promise<string>
358
+ callAccountMethod: <T = unknown>(
359
+ network: string,
360
+ accountIndex: number,
361
+ methodName: string,
362
+ args?: unknown
363
+ ) => Promise<T>
364
+ }
365
+ ```
366
+
367
+ ### useBalance()
368
+
369
+ ```typescript
370
+ function useBalance(options: {
371
+ network: string
372
+ accountIndex: number
373
+ tokenAddress: string | null
374
+ walletId?: string
375
+ enabled?: boolean
376
+ refetchInterval?: number
377
+ staleTime?: number
378
+ }): {
379
+ data: string | null
380
+ isLoading: boolean
381
+ error: Error | null
382
+ refetch: () => void
383
+ }
384
+ ```
385
+
386
+ ### useWalletManager()
387
+
388
+ ```typescript
389
+ interface UseWalletManagerResult {
390
+ createWallet: (identifier?: string) => Promise<void>
391
+ loadWallet: (identifier?: string) => Promise<void>
392
+ importWallet: (mnemonic: string, identifier?: string) => Promise<void>
393
+ deleteWallet: (identifier: string) => Promise<void>
394
+ hasWallet: (identifier?: string) => Promise<boolean>
395
+ getWalletList: () => Wallet[]
396
+ activeWalletId: string | null
397
+ }
398
+ ```
399
+
400
+ ### Allowed Account Methods
401
+
402
+ For security, only these methods can be called via `callAccountMethod`:
403
+
404
+ - `getAddress` - Get wallet address
405
+ - `getBalance` - Get native token balance
406
+ - `getTokenBalance` - Get ERC20 token balance
407
+ - `signMessage` - Sign a message
408
+ - `signTransaction` - Sign a transaction
409
+ - `sendTransaction` - Send a transaction
410
+
411
+ ## Architecture
412
+
413
+ ```
414
+ ┌─────────────────────────────────────┐
415
+ │ App Layer (Hooks) │
416
+ │ useWallet, useBalance, useWdkApp │
417
+ └──────────────┬──────────────────────┘
418
+
419
+ ┌──────────────▼──────────────────────┐
420
+ │ Provider Layer │
421
+ │ WdkAppProvider │
422
+ │ (Consolidated state sync effect) │
423
+ └──────────────┬──────────────────────┘
424
+
425
+ ┌──────────────▼──────────────────────┐
426
+ │ Service Layer │
427
+ │ WorkletLifecycleService │
428
+ │ AddressService │
429
+ │ AccountService │
430
+ │ BalanceService │
431
+ │ WalletSetupService │
432
+ │ WalletSwitchingService │
433
+ └──────────────┬──────────────────────┘
434
+
435
+ ┌──────────────▼──────────────────────┐
436
+ │ State Management │
437
+ │ WorkletStore (Zustand) │
438
+ │ WalletStore (Zustand) │
439
+ │ TanStack Query (Balances) │
440
+ │ Operation Mutex (Race prevention) │
441
+ └──────────────┬──────────────────────┘
442
+
443
+ ┌──────────────▼──────────────────────┐
444
+ │ Storage Layer │
445
+ │ MMKV (non-sensitive) │
446
+ │ SecureStorage (sensitive) │
447
+ └─────────────────────────────────────┘
448
+ ```
449
+
450
+ ### State Synchronization
451
+
452
+ The `WdkAppProvider` uses a **consolidated effect** for wallet state synchronization to prevent race conditions. Multiple interdependent state changes (activeWalletId, addresses, loadingState, errors) must be evaluated atomically in a single effect. See [WALLET_STATE_MACHINE.md](src/store/WALLET_STATE_MACHINE.md) for detailed state machine documentation.
453
+
454
+ ### Key Services
455
+
456
+ - **WorkletLifecycleService**: Manages worklet lifecycle (start, initialize, cleanup)
457
+ - **AddressService**: Handles address retrieval and caching
458
+ - **AccountService**: Handles account method calls with whitelist validation
459
+ - **BalanceService**: Manages balance operations
460
+ - **WalletSetupService**: Handles wallet creation, import, and credential management
461
+
462
+ ## Security
463
+
464
+ ### Storage Encryption
465
+
466
+ - **MMKV Storage**: Uses cryptographic key derivation for non-sensitive data
467
+ - **Secure Storage**: Uses device keychain with biometric authentication for sensitive data
468
+ - **Memory Management**: Sensitive data is automatically cleared when app is backgrounded
469
+
470
+ ### Security Features
471
+
472
+ - ✅ Method whitelist validation (only approved methods can be called)
473
+ - ✅ Input validation and sanitization
474
+ - ✅ Error message sanitization (prevents information leakage)
475
+ - ✅ Automatic credential cache expiration (TTL: 5 minutes, LRU eviction at 15 entries)
476
+ - ✅ Safe JSON stringification (prevents prototype pollution)
477
+ - ✅ Runtime type validation with Zod schemas
478
+ - ✅ Operation mutex with timeout protection (prevents stuck operations)
479
+ - ✅ Automatic sensitive data cleanup on app background
480
+
481
+ ### Best Practices
482
+
483
+ 1. Always use `WdkAppProvider` at app root
484
+ 2. Validate inputs before use (use provided validation utilities)
485
+ 3. Never log sensitive data
486
+ 4. Use error boundaries to handle errors gracefully
487
+ 5. Sensitive data is automatically cleared on app background
488
+
489
+ ## Troubleshooting
490
+
491
+ ### Wallet Initialization Fails
492
+
493
+ **Symptoms**: `status` is `ERROR`, `error` is set
494
+
495
+ **Solutions**:
496
+ 1. Check that `networkConfigs` are valid (use `validateNetworkConfigs()`)
497
+ 2. Verify `tokenConfigs` are properly configured
498
+ 3. Check console logs for detailed error messages
499
+ 4. Try calling `retry()` method from context
500
+
501
+ **Common Errors**:
502
+ - "WDK not initialized" → Worklet failed to start, check network configs
503
+ - "Biometric authentication required" → User cancelled or device doesn't support biometrics
504
+ - "Encryption key not found" → Secure storage issue, may need to recreate wallet
505
+
506
+ ### Balance Fetching Issues
507
+
508
+ **Symptoms**: Balances not updating, `isLoading` stuck true
509
+
510
+ **Solutions**:
511
+ 1. Verify `tokenConfigs` are properly configured
512
+ 2. Check network connectivity and RPC endpoint availability
513
+ 3. Ensure wallet is initialized (`status === 'READY'`)
514
+ 4. Check token addresses are valid Ethereum addresses
515
+
516
+ ### Type Validation Errors
517
+
518
+ **Symptoms**: Runtime errors about invalid types
519
+
520
+ **Solutions**:
521
+ 1. Use `validateNetworkConfigs()` and `validateTokenConfigs()` before passing to provider
522
+ 2. Ensure token addresses match Ethereum address format
523
+ 3. Verify account indices are non-negative integers
524
+ 4. Use type guards from exports for runtime validation
525
+
526
+ ## Development
527
+
528
+ ### Building
529
+
530
+ ```bash
531
+ npm run build
532
+ npm run build:strict # Strict mode (fails on errors)
533
+ ```
534
+
535
+ ### Testing
536
+
537
+ ```bash
538
+ npm test
539
+ npm run test:coverage # 100% coverage required
540
+ npm run test:watch
541
+ ```
542
+
543
+ ### Type Checking
544
+
545
+ ```bash
546
+ npm run typecheck
547
+ ```
548
+
549
+ ## License
550
+
551
+ Apache-2.0
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Mock React module for Jest tests
3
+ * Required by Zustand v5 which imports React
4
+ */
5
+ export declare const useState: jest.Mock<any[], [initial: any], any>;
6
+ export declare const useEffect: jest.Mock<any, any, any>;
7
+ export declare const useCallback: jest.Mock<any, [fn: any], any>;
8
+ export declare const useMemo: jest.Mock<any, [fn: any], any>;
9
+ export declare const useRef: jest.Mock<{
10
+ current: any;
11
+ }, [initial: any], any>;
12
+ export declare const createContext: jest.Mock<{
13
+ Provider: ({ children }: any) => any;
14
+ Consumer: ({ children }: any) => any;
15
+ }, [], any>;
16
+ export declare const useContext: jest.Mock<any, any, any>;
17
+ export declare const useReducer: jest.Mock<any[], [reducer: any, initial: any], any>;
18
+ export declare class Component {
19
+ }
20
+ export declare const Fragment: ({ children }: any) => any;
21
+ export declare const version = "18.0.0";
22
+ declare const _default: {
23
+ useState: jest.Mock<any[], [initial: any], any>;
24
+ useEffect: jest.Mock<any, any, any>;
25
+ useCallback: jest.Mock<any, [fn: any], any>;
26
+ useMemo: jest.Mock<any, [fn: any], any>;
27
+ useRef: jest.Mock<{
28
+ current: any;
29
+ }, [initial: any], any>;
30
+ createContext: jest.Mock<{
31
+ Provider: ({ children }: any) => any;
32
+ Consumer: ({ children }: any) => any;
33
+ }, [], any>;
34
+ useContext: jest.Mock<any, any, any>;
35
+ useReducer: jest.Mock<any[], [reducer: any, initial: any], any>;
36
+ Component: typeof Component;
37
+ Fragment: ({ children }: any) => any;
38
+ version: string;
39
+ };
40
+ export default _default;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Mock React module for Jest tests
3
+ * Required by Zustand v5 which imports React
4
+ */
5
+ export const useState = jest.fn((initial) => [initial, jest.fn()]);
6
+ export const useEffect = jest.fn();
7
+ export const useCallback = jest.fn((fn) => fn);
8
+ export const useMemo = jest.fn((fn) => fn());
9
+ export const useRef = jest.fn((initial) => ({ current: initial }));
10
+ export const createContext = jest.fn(() => ({
11
+ Provider: ({ children }) => children,
12
+ Consumer: ({ children }) => children,
13
+ }));
14
+ export const useContext = jest.fn();
15
+ export const useReducer = jest.fn((reducer, initial) => [initial, jest.fn()]);
16
+ export class Component {
17
+ }
18
+ export const Fragment = ({ children }) => children;
19
+ export const version = '18.0.0';
20
+ export default {
21
+ useState,
22
+ useEffect,
23
+ useCallback,
24
+ useMemo,
25
+ useRef,
26
+ createContext,
27
+ useContext,
28
+ useReducer,
29
+ Component,
30
+ Fragment,
31
+ version,
32
+ };
33
+ //# sourceMappingURL=react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.js","sourceRoot":"","sources":["../../src/__mocks__/react.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,OAAY,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;AACvE,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,CAAC,EAAE,EAAE,CAAA;AAClC,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,EAAO,EAAE,EAAE,CAAC,EAAE,CAAC,CAAA;AACnD,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,EAAO,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAA;AACjD,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,OAAY,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,CAAA;AACvE,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;IAC1C,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAO,EAAE,EAAE,CAAC,QAAQ;IACzC,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAO,EAAE,EAAE,CAAC,QAAQ;CAC1C,CAAC,CAAC,CAAA;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC,EAAE,EAAE,CAAA;AACnC,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,OAAY,EAAE,OAAY,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;AACvF,MAAM,OAAO,SAAS;CAAG;AACzB,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,EAAE,QAAQ,EAAO,EAAE,EAAE,CAAC,QAAQ,CAAA;AACvD,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,CAAA;AAE/B,eAAe;IACb,QAAQ;IACR,SAAS;IACT,WAAW;IACX,OAAO;IACP,MAAM;IACN,aAAa;IACb,UAAU;IACV,UAAU;IACV,SAAS;IACT,QAAQ;IACR,OAAO;CACR,CAAA"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Mock SecureStorage for testing
3
+ *
4
+ * Supports identifier parameter for multi-wallet testing
5
+ */
6
+ export declare const mockSecureStorage: {
7
+ authenticate: jest.Mock<Promise<boolean>, [], any>;
8
+ hasWallet: jest.Mock<Promise<boolean>, [identifier?: string | undefined], any>;
9
+ setEncryptionKey: jest.Mock<Promise<void>, [key: string, identifier?: string | undefined], any>;
10
+ getEncryptionKey: jest.Mock<Promise<string | null>, [identifier?: string | undefined], any>;
11
+ setEncryptedSeed: jest.Mock<Promise<void>, [seed: string, identifier?: string | undefined], any>;
12
+ getEncryptedSeed: jest.Mock<Promise<string | null>, [identifier?: string | undefined], any>;
13
+ setEncryptedEntropy: jest.Mock<Promise<void>, [entropy: string, identifier?: string | undefined], any>;
14
+ getEncryptedEntropy: jest.Mock<Promise<string | null>, [identifier?: string | undefined], any>;
15
+ getAllEncrypted: jest.Mock<Promise<{
16
+ encryptedSeed: string | null;
17
+ encryptedEntropy: string | null;
18
+ encryptionKey: string | null;
19
+ }>, [identifier?: string | undefined], any>;
20
+ clearAll: jest.Mock<Promise<void>, [], any>;
21
+ isBiometricAvailable: jest.Mock<Promise<boolean>, [], any>;
22
+ deleteWallet: jest.Mock<Promise<void>, [identifier?: string | undefined], any>;
23
+ cleanup: jest.Mock<any, any, any>;
24
+ _clearStorage: () => void;
25
+ };
26
+ export default mockSecureStorage;