@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,190 @@
1
+ /**
2
+ * Zod Schemas for Runtime Validation
3
+ *
4
+ * Provides Zod schemas for all WDK types to replace manual if/else type guards.
5
+ * These schemas provide better error messages and are easier to maintain.
6
+ */
7
+
8
+ import { z } from 'zod'
9
+
10
+ /**
11
+ * Ethereum address schema (0x followed by 40 hex characters)
12
+ */
13
+ export const ethereumAddressSchema = z.string().regex(/^0x[a-fA-F0-9]{40}$/, {
14
+ message: 'Must be a valid Ethereum address (0x followed by 40 hex characters)',
15
+ })
16
+
17
+ /**
18
+ * Spark address schema (Bech32 format: spark1/sparkt1/sparkrt1 followed by base32 characters)
19
+ */
20
+ export const sparkAddressSchema = z.string().regex(/^spark(1|t1|rt1|test1)[a-z0-9]+$/, {
21
+ message: 'Must be a valid Spark address (spark1/sparkt1/sparkrt1 followed by base32 characters)',
22
+ }).min(14).max(90)
23
+
24
+ /**
25
+ * Address schema (Ethereum or Spark)
26
+ */
27
+ export const addressSchema = z.union([ethereumAddressSchema, sparkAddressSchema])
28
+
29
+ /**
30
+ * Network configuration schema
31
+ */
32
+ export const networkConfigSchema = z.object({
33
+ chainId: z.number().int().positive(),
34
+ blockchain: z.string().min(1),
35
+ provider: z.string().min(1).optional(),
36
+ bundlerUrl: z.string().min(1).optional(),
37
+ paymasterUrl: z.string().min(1).optional(),
38
+ paymasterAddress: ethereumAddressSchema.optional(),
39
+ entryPointAddress: ethereumAddressSchema.optional(),
40
+ transferMaxFee: z.number().nonnegative().optional(),
41
+ })
42
+
43
+ /**
44
+ * Network configurations schema
45
+ */
46
+ export const networkConfigsSchema = z.record(
47
+ z.string().regex(/^[a-zA-Z0-9_-]+$/, {
48
+ message: 'Network name must contain only alphanumeric characters, hyphens, and underscores',
49
+ }),
50
+ networkConfigSchema
51
+ ).refine((configs) => Object.keys(configs).length > 0, {
52
+ message: 'NetworkConfigs must contain at least one network',
53
+ })
54
+
55
+ /**
56
+ * Token configuration schema
57
+ */
58
+ export const tokenConfigSchema = z.object({
59
+ symbol: z.string().min(1),
60
+ name: z.string().min(1),
61
+ decimals: z.number().int().min(0).max(18),
62
+ address: z.union([ethereumAddressSchema, z.null()]),
63
+ })
64
+
65
+ /**
66
+ * Network tokens schema
67
+ */
68
+ export const networkTokensSchema = z.object({
69
+ native: tokenConfigSchema,
70
+ tokens: z.array(tokenConfigSchema),
71
+ })
72
+
73
+ /**
74
+ * Token configurations schema
75
+ */
76
+ export const tokenConfigsSchema = z.record(
77
+ z.string().min(1),
78
+ networkTokensSchema
79
+ ).refine((configs) => Object.keys(configs).length > 0, {
80
+ message: 'TokenConfigs must contain at least one network',
81
+ })
82
+
83
+ /**
84
+ * Account index schema
85
+ */
86
+ export const accountIndexSchema = z.number().int().nonnegative()
87
+
88
+ /**
89
+ * Network name schema
90
+ */
91
+ export const networkNameSchema = z.string().regex(/^[a-zA-Z0-9_-]+$/, {
92
+ message: 'Network name must contain only alphanumeric characters, hyphens, and underscores',
93
+ }).min(1)
94
+
95
+ /**
96
+ * Balance string schema (valid number string)
97
+ */
98
+ export const balanceStringSchema = z.string().regex(/^-?\d+(\.\d+)?$/, {
99
+ message: 'Balance must be a valid number string',
100
+ })
101
+
102
+ /**
103
+ * Wallet addresses schema
104
+ * Maps network -> accountIndex -> address
105
+ */
106
+ export const walletAddressesSchema = z.record(
107
+ networkNameSchema,
108
+ z.record(
109
+ z.string().transform((val) => {
110
+ const num = parseInt(val, 10)
111
+ if (isNaN(num) || num < 0) {
112
+ throw new Error('Account index must be a non-negative integer')
113
+ }
114
+ return num
115
+ }),
116
+ addressSchema
117
+ )
118
+ )
119
+
120
+ /**
121
+ * Wallet balances schema
122
+ * Maps network -> accountIndex -> tokenAddress -> balance
123
+ */
124
+ export const walletBalancesSchema = z.record(
125
+ networkNameSchema,
126
+ z.record(
127
+ z.string().transform((val) => {
128
+ const num = parseInt(val, 10)
129
+ if (isNaN(num) || num < 0) {
130
+ throw new Error('Account index must be a non-negative integer')
131
+ }
132
+ return num
133
+ }),
134
+ z.record(z.string(), balanceStringSchema)
135
+ )
136
+ )
137
+
138
+ /**
139
+ * Balance loading states schema
140
+ * Maps "network-accountIndex-tokenAddress" -> boolean
141
+ */
142
+ export const balanceLoadingStatesSchema = z.record(z.string(), z.boolean())
143
+
144
+ /**
145
+ * Balance fetch result schema
146
+ */
147
+ export const balanceFetchResultSchema = z.object({
148
+ success: z.boolean(),
149
+ network: networkNameSchema,
150
+ accountIndex: accountIndexSchema,
151
+ tokenAddress: z.union([ethereumAddressSchema, z.null()]),
152
+ balance: z.union([balanceStringSchema, z.null()]),
153
+ error: z.string().optional(),
154
+ })
155
+
156
+ /**
157
+ * Wallet schema
158
+ */
159
+ export const walletSchema = z.object({
160
+ accountIndex: accountIndexSchema,
161
+ identifier: z.string().min(1),
162
+ name: z.string().min(1),
163
+ createdAt: z.number().int().nonnegative(),
164
+ updatedAt: z.number().int().nonnegative(),
165
+ })
166
+
167
+ /**
168
+ * Worklet response schemas for runtime validation
169
+ */
170
+ export const workletResponseSchema = z.object({
171
+ result: z.string(),
172
+ error: z.string().optional(),
173
+ })
174
+
175
+ /**
176
+ * Balance response schema (numeric string)
177
+ */
178
+ export const balanceResponseSchema = z.string().regex(/^\d+$/, {
179
+ message: 'Balance must be a numeric string',
180
+ })
181
+
182
+ /**
183
+ * Account method response schema (union of possible return types)
184
+ */
185
+ export const accountMethodResponseSchema = z.union([
186
+ balanceResponseSchema,
187
+ z.string(), // For addresses
188
+ z.object({}).passthrough(), // For other responses (objects)
189
+ ])
190
+
@@ -0,0 +1,236 @@
1
+ /**
2
+ * Store helper utilities
3
+ *
4
+ * Provides common patterns for accessing and validating store state
5
+ * to reduce code duplication across services.
6
+ */
7
+
8
+ import type { HRPC } from '@spacesops/pear-wrk-wdk'
9
+
10
+ import { getWorkletStore } from '../store/workletStore'
11
+ import { getWalletStore } from '../store/walletStore'
12
+ import { asExtendedHRPC } from '../types/hrpc'
13
+ import type { WalletState } from '../store/walletStore'
14
+
15
+ /**
16
+ * Require that worklet is initialized and return HRPC instance
17
+ *
18
+ * @throws Error if worklet is not initialized
19
+ * @returns HRPC instance
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * const hrpc = requireInitialized()
24
+ * await hrpc.callMethod(...)
25
+ * ```
26
+ */
27
+ export function requireInitialized(): HRPC {
28
+ const state = getWorkletStore().getState()
29
+ if (!state.isInitialized || !state.hrpc) {
30
+ throw new Error('WDK not initialized')
31
+ }
32
+ return state.hrpc
33
+ }
34
+
35
+ /**
36
+ * Require that worklet is initialized and return extended HRPC instance
37
+ *
38
+ * @throws Error if worklet is not initialized
39
+ * @returns Extended HRPC instance
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * const hrpc = requireExtendedHRPC()
44
+ * await hrpc.initializeWDK(...)
45
+ * ```
46
+ */
47
+ export function requireExtendedHRPC(): ReturnType<typeof asExtendedHRPC> {
48
+ const hrpc = requireInitialized()
49
+ return asExtendedHRPC(hrpc)
50
+ }
51
+
52
+ /**
53
+ * Check if worklet is initialized
54
+ *
55
+ * @returns true if worklet is initialized, false otherwise
56
+ */
57
+ export function isInitialized(): boolean {
58
+ const state = getWorkletStore().getState()
59
+ return state.isInitialized && state.hrpc !== null
60
+ }
61
+
62
+ /**
63
+ * Update balance in wallet state (helper for nested state updates)
64
+ *
65
+ * @param prev - Previous wallet state
66
+ * @param walletId - Wallet identifier
67
+ * @param network - Network name
68
+ * @param accountIndex - Account index
69
+ * @param tokenKey - Token key (address or 'native')
70
+ * @param balance - Balance value
71
+ * @returns Partial state update
72
+ */
73
+ export function updateBalanceInState(
74
+ prev: WalletState,
75
+ walletId: string,
76
+ network: string,
77
+ accountIndex: number,
78
+ tokenKey: string,
79
+ balance: string
80
+ ): Partial<WalletState> {
81
+ const walletBalances = prev.balances[walletId] || {}
82
+ const networkBalances = walletBalances[network] || {}
83
+ const accountBalances = networkBalances[accountIndex] || {}
84
+ return {
85
+ balances: {
86
+ ...prev.balances,
87
+ [walletId]: {
88
+ ...walletBalances,
89
+ [network]: {
90
+ ...networkBalances,
91
+ [accountIndex]: {
92
+ ...accountBalances,
93
+ [tokenKey]: balance,
94
+ },
95
+ },
96
+ },
97
+ },
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Update address in wallet state (helper for nested state updates)
103
+ *
104
+ * @param prev - Previous wallet state
105
+ * @param walletId - Wallet identifier
106
+ * @param network - Network name
107
+ * @param accountIndex - Account index
108
+ * @param address - Address value
109
+ * @returns Partial state update
110
+ */
111
+ export function updateAddressInState(
112
+ prev: WalletState,
113
+ walletId: string,
114
+ network: string,
115
+ accountIndex: number,
116
+ address: string
117
+ ): Partial<WalletState> {
118
+ const walletAddresses = prev.addresses[walletId] || {}
119
+ const networkAddresses = walletAddresses[network] || {}
120
+ return {
121
+ addresses: {
122
+ ...prev.addresses,
123
+ [walletId]: {
124
+ ...walletAddresses,
125
+ [network]: {
126
+ ...networkAddresses,
127
+ [accountIndex]: address,
128
+ },
129
+ },
130
+ },
131
+ }
132
+ }
133
+
134
+ /**
135
+ * Resolve wallet identifier from parameter or store
136
+ *
137
+ * This helper function standardizes the pattern for resolving walletId across the codebase.
138
+ * It checks the provided walletId parameter first, then falls back to activeWalletId from store,
139
+ * and finally to '__temporary__' if no wallet is active.
140
+ *
141
+ * @param walletId - Optional wallet identifier parameter
142
+ * @returns Resolved wallet identifier (never null)
143
+ *
144
+ * @example
145
+ * ```typescript
146
+ * const targetWalletId = resolveWalletId(walletId)
147
+ * // Use targetWalletId for operations
148
+ * ```
149
+ */
150
+ export function resolveWalletId(walletId?: string): string {
151
+ if (walletId) {
152
+ return walletId
153
+ }
154
+
155
+ const walletStore = getWalletStore()
156
+ const activeWalletId = walletStore.getState().activeWalletId
157
+
158
+ return activeWalletId || '__temporary__'
159
+ }
160
+
161
+ /**
162
+ * Safely get nested property from an object
163
+ *
164
+ * @param obj - Object to access
165
+ * @param path - Array of keys representing the path
166
+ * @param defaultValue - Default value if path doesn't exist
167
+ * @returns Value at path or default value
168
+ *
169
+ * @example
170
+ * ```typescript
171
+ * const balance = getNestedState(state.balances, [walletId, network, accountIndex, tokenKey], null)
172
+ * ```
173
+ */
174
+ export function getNestedState<T>(
175
+ obj: Record<string, unknown>,
176
+ path: (string | number)[],
177
+ defaultValue: T
178
+ ): T {
179
+ let current: unknown = obj
180
+ for (const key of path) {
181
+ if (current == null || typeof current !== 'object') {
182
+ return defaultValue
183
+ }
184
+ if (!(key in current)) {
185
+ return defaultValue
186
+ }
187
+ current = (current as Record<string | number, unknown>)[key]
188
+ }
189
+ return (current as T) ?? defaultValue
190
+ }
191
+
192
+ /**
193
+ * Update nested state structure (generic helper for deep state updates)
194
+ *
195
+ * Creates a new nested object structure with the updated value at the specified path.
196
+ * All intermediate objects are shallow copied to maintain immutability.
197
+ *
198
+ * @param prev - Previous state object
199
+ * @param path - Array of keys representing the path to update
200
+ * @param value - Value to set at the path
201
+ * @returns New state object with updated value
202
+ *
203
+ * @example
204
+ * ```typescript
205
+ * const newState = updateNestedState(prev, ['balances', walletId, network, accountIndex, tokenKey], balance)
206
+ * ```
207
+ */
208
+ export function updateNestedState<T extends Record<string, unknown>>(
209
+ prev: T,
210
+ path: (string | number)[],
211
+ value: unknown
212
+ ): Partial<T> {
213
+ if (path.length === 0) {
214
+ if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
215
+ return { ...prev, ...(value as Partial<T>) }
216
+ }
217
+ return prev
218
+ }
219
+
220
+ const [firstKey, ...restPath] = path
221
+ const keyString = String(firstKey)
222
+ const currentValue = prev[keyString]
223
+ const currentValueObj = (typeof currentValue === 'object' && currentValue !== null && !Array.isArray(currentValue))
224
+ ? (currentValue as Record<string | number, unknown>)
225
+ : {}
226
+ const updatedValue = restPath.length > 0
227
+ ? updateNestedState(currentValueObj, restPath, value)
228
+ : value
229
+
230
+ return {
231
+ ...prev,
232
+ [keyString]: updatedValue,
233
+ } as Partial<T>
234
+ }
235
+
236
+
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Runtime Type Guards
3
+ *
4
+ * Provides runtime type checking for critical data paths to ensure type safety
5
+ * beyond TypeScript's compile-time checks.
6
+ *
7
+ * NOTE: These type guards now use Zod schemas internally for validation.
8
+ * They are kept for backward compatibility but may be deprecated in the future.
9
+ */
10
+
11
+ import {
12
+ networkConfigSchema,
13
+ networkConfigsSchema,
14
+ tokenConfigSchema,
15
+ tokenConfigsSchema,
16
+ walletAddressesSchema,
17
+ walletBalancesSchema,
18
+ ethereumAddressSchema,
19
+ sparkAddressSchema,
20
+ accountIndexSchema,
21
+ networkNameSchema,
22
+ balanceStringSchema,
23
+ } from './schemas'
24
+ import type {
25
+ NetworkConfig,
26
+ NetworkConfigs,
27
+ TokenConfig,
28
+ TokenConfigs,
29
+ WalletAddresses,
30
+ WalletBalances,
31
+ } from '../types'
32
+
33
+ /**
34
+ * Type guard to check if a value is a valid NetworkConfig
35
+ * Uses Zod schema internally for validation
36
+ */
37
+ export function isNetworkConfig(value: unknown): value is NetworkConfig {
38
+ return networkConfigSchema.safeParse(value).success
39
+ }
40
+
41
+ /**
42
+ * Type guard to check if a value is a valid NetworkConfigs
43
+ * Uses Zod schema internally for validation
44
+ */
45
+ export function isNetworkConfigs(value: unknown): value is NetworkConfigs {
46
+ return networkConfigsSchema.safeParse(value).success
47
+ }
48
+
49
+ /**
50
+ * Type guard to check if a value is a valid TokenConfig
51
+ * Uses Zod schema internally for validation
52
+ */
53
+ export function isTokenConfig(value: unknown): value is TokenConfig {
54
+ return tokenConfigSchema.safeParse(value).success
55
+ }
56
+
57
+ /**
58
+ * Type guard to check if a value is a valid TokenConfigs
59
+ * Uses Zod schema internally for validation
60
+ */
61
+ export function isTokenConfigs(value: unknown): value is TokenConfigs {
62
+ return tokenConfigsSchema.safeParse(value).success
63
+ }
64
+
65
+ /**
66
+ * Type guard to check if a value is a valid WalletAddresses structure
67
+ * Uses Zod schema internally for validation
68
+ */
69
+ export function isWalletAddresses(value: unknown): value is WalletAddresses {
70
+ return walletAddressesSchema.safeParse(value).success
71
+ }
72
+
73
+ /**
74
+ * Type guard to check if a value is a valid WalletBalances structure
75
+ * Uses Zod schema internally for validation
76
+ */
77
+ export function isWalletBalances(value: unknown): value is WalletBalances {
78
+ return walletBalancesSchema.safeParse(value).success
79
+ }
80
+
81
+ /**
82
+ * Type guard to check if a value is a valid Ethereum address
83
+ * Uses Zod schema internally for validation
84
+ */
85
+ export function isEthereumAddress(value: unknown): value is string {
86
+ return ethereumAddressSchema.safeParse(value).success
87
+ }
88
+
89
+ /**
90
+ * Type guard to check if a value is a valid Spark address (Bech32 format)
91
+ * Spark addresses start with "spark1" followed by Bech32-encoded characters
92
+ * Uses Zod schema internally for validation
93
+ */
94
+ export function isSparkAddress(value: unknown): value is string {
95
+ return sparkAddressSchema.safeParse(value).success
96
+ }
97
+
98
+ /**
99
+ * Type guard to check if a value is a valid address (Ethereum or Spark format)
100
+ */
101
+ export function isValidAddress(value: unknown): value is string {
102
+ return isEthereumAddress(value) || isSparkAddress(value)
103
+ }
104
+
105
+ /**
106
+ * Type guard to check if a value is a valid account index
107
+ * Uses Zod schema internally for validation
108
+ */
109
+ export function isValidAccountIndex(value: unknown): value is number {
110
+ return accountIndexSchema.safeParse(value).success
111
+ }
112
+
113
+ /**
114
+ * Type guard to check if a value is a valid network name
115
+ * Uses Zod schema internally for validation
116
+ */
117
+ export function isValidNetworkName(value: unknown): value is string {
118
+ return networkNameSchema.safeParse(value).success
119
+ }
120
+
121
+ /**
122
+ * Type guard to check if a value is a valid balance string
123
+ * Uses Zod schema internally for validation
124
+ */
125
+ export function isValidBalanceString(value: unknown): value is string {
126
+ return balanceStringSchema.safeParse(value).success
127
+ }
128
+
129
+