movehat 0.1.9 → 0.2.1

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 (445) hide show
  1. package/README.md +132 -279
  2. package/dist/__tests__/deployContract.test.d.ts +2 -0
  3. package/dist/__tests__/deployContract.test.d.ts.map +1 -0
  4. package/dist/__tests__/deployContract.test.js +368 -0
  5. package/dist/__tests__/deployContract.test.js.map +1 -0
  6. package/dist/__tests__/errors.test.d.ts +2 -0
  7. package/dist/__tests__/errors.test.d.ts.map +1 -0
  8. package/dist/__tests__/errors.test.js +46 -0
  9. package/dist/__tests__/errors.test.js.map +1 -0
  10. package/dist/__tests__/fixtures/sigint-deploy-harness.d.ts +24 -0
  11. package/dist/__tests__/fixtures/sigint-deploy-harness.d.ts.map +1 -0
  12. package/dist/__tests__/fixtures/sigint-deploy-harness.js +82 -0
  13. package/dist/__tests__/fixtures/sigint-deploy-harness.js.map +1 -0
  14. package/dist/__tests__/fork/api.test.d.ts +2 -0
  15. package/dist/__tests__/fork/api.test.d.ts.map +1 -0
  16. package/dist/__tests__/fork/api.test.js +110 -0
  17. package/dist/__tests__/fork/api.test.js.map +1 -0
  18. package/dist/__tests__/harness/Harness.createLive.test.d.ts +2 -0
  19. package/dist/__tests__/harness/Harness.createLive.test.d.ts.map +1 -0
  20. package/dist/__tests__/harness/Harness.createLive.test.js +53 -0
  21. package/dist/__tests__/harness/Harness.createLive.test.js.map +1 -0
  22. package/dist/__tests__/harness/Harness.proxy.test.d.ts +2 -0
  23. package/dist/__tests__/harness/Harness.proxy.test.d.ts.map +1 -0
  24. package/dist/__tests__/harness/Harness.proxy.test.js +89 -0
  25. package/dist/__tests__/harness/Harness.proxy.test.js.map +1 -0
  26. package/dist/__tests__/harness/_fixture.d.ts +54 -0
  27. package/dist/__tests__/harness/_fixture.d.ts.map +1 -0
  28. package/dist/__tests__/harness/_fixture.js +69 -0
  29. package/dist/__tests__/harness/_fixture.js.map +1 -0
  30. package/dist/__tests__/harness/codeObject.deploy.test.d.ts +2 -0
  31. package/dist/__tests__/harness/codeObject.deploy.test.d.ts.map +1 -0
  32. package/dist/__tests__/harness/codeObject.deploy.test.js +288 -0
  33. package/dist/__tests__/harness/codeObject.deploy.test.js.map +1 -0
  34. package/dist/__tests__/harness/codeObject.upgrade.test.d.ts +2 -0
  35. package/dist/__tests__/harness/codeObject.upgrade.test.d.ts.map +1 -0
  36. package/dist/__tests__/harness/codeObject.upgrade.test.js +138 -0
  37. package/dist/__tests__/harness/codeObject.upgrade.test.js.map +1 -0
  38. package/dist/__tests__/harness/script.test.d.ts +2 -0
  39. package/dist/__tests__/harness/script.test.d.ts.map +1 -0
  40. package/dist/__tests__/harness/script.test.js +219 -0
  41. package/dist/__tests__/harness/script.test.js.map +1 -0
  42. package/dist/__tests__/harness/view.test.d.ts +2 -0
  43. package/dist/__tests__/harness/view.test.d.ts.map +1 -0
  44. package/dist/__tests__/harness/view.test.js +92 -0
  45. package/dist/__tests__/harness/view.test.js.map +1 -0
  46. package/dist/__tests__/runtime.test.d.ts +2 -0
  47. package/dist/__tests__/runtime.test.d.ts.map +1 -0
  48. package/dist/__tests__/runtime.test.js +141 -0
  49. package/dist/__tests__/runtime.test.js.map +1 -0
  50. package/dist/cli.js +2 -1
  51. package/dist/cli.js.map +1 -1
  52. package/dist/commands/__tests__/compile.test.d.ts +2 -0
  53. package/dist/commands/__tests__/compile.test.d.ts.map +1 -0
  54. package/dist/commands/__tests__/compile.test.js +351 -0
  55. package/dist/commands/__tests__/compile.test.js.map +1 -0
  56. package/dist/commands/__tests__/init.test.d.ts +2 -0
  57. package/dist/commands/__tests__/init.test.d.ts.map +1 -0
  58. package/dist/commands/__tests__/init.test.js +101 -0
  59. package/dist/commands/__tests__/init.test.js.map +1 -0
  60. package/dist/commands/__tests__/run.test.d.ts +2 -0
  61. package/dist/commands/__tests__/run.test.d.ts.map +1 -0
  62. package/dist/commands/__tests__/run.test.js +166 -0
  63. package/dist/commands/__tests__/run.test.js.map +1 -0
  64. package/dist/commands/__tests__/test-move.test.d.ts +2 -0
  65. package/dist/commands/__tests__/test-move.test.d.ts.map +1 -0
  66. package/dist/commands/__tests__/test-move.test.js +59 -0
  67. package/dist/commands/__tests__/test-move.test.js.map +1 -0
  68. package/dist/commands/__tests__/test.test.d.ts +2 -0
  69. package/dist/commands/__tests__/test.test.d.ts.map +1 -0
  70. package/dist/commands/__tests__/test.test.js +168 -0
  71. package/dist/commands/__tests__/test.test.js.map +1 -0
  72. package/dist/commands/__tests__/update.test.d.ts +2 -0
  73. package/dist/commands/__tests__/update.test.d.ts.map +1 -0
  74. package/dist/commands/__tests__/update.test.js +176 -0
  75. package/dist/commands/__tests__/update.test.js.map +1 -0
  76. package/dist/commands/compile.d.ts +7 -1
  77. package/dist/commands/compile.d.ts.map +1 -1
  78. package/dist/commands/compile.js +150 -33
  79. package/dist/commands/compile.js.map +1 -1
  80. package/dist/commands/fork/__tests__/create.test.d.ts +2 -0
  81. package/dist/commands/fork/__tests__/create.test.d.ts.map +1 -0
  82. package/dist/commands/fork/__tests__/create.test.js +108 -0
  83. package/dist/commands/fork/__tests__/create.test.js.map +1 -0
  84. package/dist/commands/fork/__tests__/fund.test.d.ts +2 -0
  85. package/dist/commands/fork/__tests__/fund.test.d.ts.map +1 -0
  86. package/dist/commands/fork/__tests__/fund.test.js +72 -0
  87. package/dist/commands/fork/__tests__/fund.test.js.map +1 -0
  88. package/dist/commands/fork/__tests__/list.test.d.ts +2 -0
  89. package/dist/commands/fork/__tests__/list.test.d.ts.map +1 -0
  90. package/dist/commands/fork/__tests__/list.test.js +119 -0
  91. package/dist/commands/fork/__tests__/list.test.js.map +1 -0
  92. package/dist/commands/fork/__tests__/serve.test.d.ts +2 -0
  93. package/dist/commands/fork/__tests__/serve.test.d.ts.map +1 -0
  94. package/dist/commands/fork/__tests__/serve.test.js +97 -0
  95. package/dist/commands/fork/__tests__/serve.test.js.map +1 -0
  96. package/dist/commands/fork/__tests__/view-resource.test.d.ts +2 -0
  97. package/dist/commands/fork/__tests__/view-resource.test.d.ts.map +1 -0
  98. package/dist/commands/fork/__tests__/view-resource.test.js +77 -0
  99. package/dist/commands/fork/__tests__/view-resource.test.js.map +1 -0
  100. package/dist/commands/fork/create.d.ts +1 -1
  101. package/dist/commands/fork/create.d.ts.map +1 -1
  102. package/dist/commands/fork/create.js +3 -2
  103. package/dist/commands/fork/create.js.map +1 -1
  104. package/dist/commands/fork/fund.d.ts.map +1 -1
  105. package/dist/commands/fork/fund.js +15 -8
  106. package/dist/commands/fork/fund.js.map +1 -1
  107. package/dist/commands/fork/list.d.ts.map +1 -1
  108. package/dist/commands/fork/list.js +2 -1
  109. package/dist/commands/fork/list.js.map +1 -1
  110. package/dist/commands/fork/serve.d.ts +1 -0
  111. package/dist/commands/fork/serve.d.ts.map +1 -1
  112. package/dist/commands/fork/serve.js +4 -2
  113. package/dist/commands/fork/serve.js.map +1 -1
  114. package/dist/commands/fork/view-resource.d.ts.map +1 -1
  115. package/dist/commands/fork/view-resource.js +10 -5
  116. package/dist/commands/fork/view-resource.js.map +1 -1
  117. package/dist/commands/run.d.ts +15 -0
  118. package/dist/commands/run.d.ts.map +1 -1
  119. package/dist/commands/run.js +50 -27
  120. package/dist/commands/run.js.map +1 -1
  121. package/dist/commands/test-move.d.ts.map +1 -1
  122. package/dist/commands/test-move.js +3 -2
  123. package/dist/commands/test-move.js.map +1 -1
  124. package/dist/commands/test.js +52 -46
  125. package/dist/commands/test.js.map +1 -1
  126. package/dist/commands/update.d.ts.map +1 -1
  127. package/dist/commands/update.js +15 -13
  128. package/dist/commands/update.js.map +1 -1
  129. package/dist/core/AccountManager.d.ts +1 -4
  130. package/dist/core/AccountManager.d.ts.map +1 -1
  131. package/dist/core/AccountManager.js +20 -12
  132. package/dist/core/AccountManager.js.map +1 -1
  133. package/dist/core/Publisher.d.ts +26 -0
  134. package/dist/core/Publisher.d.ts.map +1 -0
  135. package/dist/core/Publisher.js +240 -0
  136. package/dist/core/Publisher.js.map +1 -0
  137. package/dist/core/__tests__/AccountManager.test.d.ts +2 -0
  138. package/dist/core/__tests__/AccountManager.test.d.ts.map +1 -0
  139. package/dist/core/__tests__/AccountManager.test.js +239 -0
  140. package/dist/core/__tests__/AccountManager.test.js.map +1 -0
  141. package/dist/core/__tests__/config.test.d.ts +2 -0
  142. package/dist/core/__tests__/config.test.d.ts.map +1 -0
  143. package/dist/core/__tests__/config.test.js +311 -0
  144. package/dist/core/__tests__/config.test.js.map +1 -0
  145. package/dist/core/__tests__/deployments.test.d.ts +2 -0
  146. package/dist/core/__tests__/deployments.test.d.ts.map +1 -0
  147. package/dist/core/__tests__/deployments.test.js +201 -0
  148. package/dist/core/__tests__/deployments.test.js.map +1 -0
  149. package/dist/core/__tests__/shell.test.d.ts +2 -0
  150. package/dist/core/__tests__/shell.test.d.ts.map +1 -0
  151. package/dist/core/__tests__/shell.test.js +107 -0
  152. package/dist/core/__tests__/shell.test.js.map +1 -0
  153. package/dist/core/config.d.ts +13 -1
  154. package/dist/core/config.d.ts.map +1 -1
  155. package/dist/core/config.js +80 -11
  156. package/dist/core/config.js.map +1 -1
  157. package/dist/core/contract.d.ts +1 -4
  158. package/dist/core/contract.d.ts.map +1 -1
  159. package/dist/core/contract.js +15 -7
  160. package/dist/core/contract.js.map +1 -1
  161. package/dist/core/deployments.d.ts +2 -8
  162. package/dist/core/deployments.d.ts.map +1 -1
  163. package/dist/core/deployments.js +8 -18
  164. package/dist/core/deployments.js.map +1 -1
  165. package/dist/core/movementProfile.d.ts +34 -0
  166. package/dist/core/movementProfile.d.ts.map +1 -0
  167. package/dist/core/movementProfile.js +150 -0
  168. package/dist/core/movementProfile.js.map +1 -0
  169. package/dist/core/shell.d.ts +23 -7
  170. package/dist/core/shell.d.ts.map +1 -1
  171. package/dist/core/shell.js +32 -14
  172. package/dist/core/shell.js.map +1 -1
  173. package/dist/errors.d.ts +35 -0
  174. package/dist/errors.d.ts.map +1 -1
  175. package/dist/errors.js +54 -0
  176. package/dist/errors.js.map +1 -1
  177. package/dist/fork/__tests__/manager.test.d.ts +2 -0
  178. package/dist/fork/__tests__/manager.test.d.ts.map +1 -0
  179. package/dist/fork/__tests__/manager.test.js +309 -0
  180. package/dist/fork/__tests__/manager.test.js.map +1 -0
  181. package/dist/fork/__tests__/server.test.d.ts +2 -0
  182. package/dist/fork/__tests__/server.test.d.ts.map +1 -0
  183. package/dist/fork/__tests__/server.test.js +54 -0
  184. package/dist/fork/__tests__/server.test.js.map +1 -0
  185. package/dist/fork/__tests__/storage.test.d.ts +2 -0
  186. package/dist/fork/__tests__/storage.test.d.ts.map +1 -0
  187. package/dist/fork/__tests__/storage.test.js +222 -0
  188. package/dist/fork/__tests__/storage.test.js.map +1 -0
  189. package/dist/fork/__tests__/test.test.d.ts +2 -0
  190. package/dist/fork/__tests__/test.test.d.ts.map +1 -0
  191. package/dist/fork/__tests__/test.test.js +81 -0
  192. package/dist/fork/__tests__/test.test.js.map +1 -0
  193. package/dist/fork/api.d.ts +14 -3
  194. package/dist/fork/api.d.ts.map +1 -1
  195. package/dist/fork/api.js +25 -14
  196. package/dist/fork/api.js.map +1 -1
  197. package/dist/fork/manager.d.ts +23 -29
  198. package/dist/fork/manager.d.ts.map +1 -1
  199. package/dist/fork/manager.js +79 -76
  200. package/dist/fork/manager.js.map +1 -1
  201. package/dist/fork/server.d.ts +11 -3
  202. package/dist/fork/server.d.ts.map +1 -1
  203. package/dist/fork/server.js +45 -13
  204. package/dist/fork/server.js.map +1 -1
  205. package/dist/fork/storage.d.ts +4 -4
  206. package/dist/fork/storage.d.ts.map +1 -1
  207. package/dist/fork/storage.js +7 -9
  208. package/dist/fork/storage.js.map +1 -1
  209. package/dist/fork/test.d.ts +12 -4
  210. package/dist/fork/test.d.ts.map +1 -1
  211. package/dist/fork/test.js +36 -27
  212. package/dist/fork/test.js.map +1 -1
  213. package/dist/harness/Harness.d.ts +118 -0
  214. package/dist/harness/Harness.d.ts.map +1 -0
  215. package/dist/harness/Harness.js +187 -0
  216. package/dist/harness/Harness.js.map +1 -0
  217. package/dist/harness/codeObject.d.ts +31 -0
  218. package/dist/harness/codeObject.d.ts.map +1 -0
  219. package/dist/harness/codeObject.js +267 -0
  220. package/dist/harness/codeObject.js.map +1 -0
  221. package/dist/harness/errors.d.ts +14 -0
  222. package/dist/harness/errors.d.ts.map +1 -0
  223. package/dist/harness/errors.js +22 -0
  224. package/dist/harness/errors.js.map +1 -0
  225. package/dist/harness/index.d.ts +4 -0
  226. package/dist/harness/index.d.ts.map +1 -0
  227. package/dist/harness/index.js +3 -0
  228. package/dist/harness/index.js.map +1 -0
  229. package/dist/harness/proxy.d.ts +7 -0
  230. package/dist/harness/proxy.d.ts.map +1 -0
  231. package/dist/harness/proxy.js +36 -0
  232. package/dist/harness/proxy.js.map +1 -0
  233. package/dist/harness/script.d.ts +21 -0
  234. package/dist/harness/script.d.ts.map +1 -0
  235. package/dist/harness/script.js +155 -0
  236. package/dist/harness/script.js.map +1 -0
  237. package/dist/harness/view.d.ts +22 -0
  238. package/dist/harness/view.d.ts.map +1 -0
  239. package/dist/harness/view.js +28 -0
  240. package/dist/harness/view.js.map +1 -0
  241. package/dist/helpers/__tests__/semver-utils.test.d.ts +2 -0
  242. package/dist/helpers/__tests__/semver-utils.test.d.ts.map +1 -0
  243. package/dist/helpers/__tests__/semver-utils.test.js +103 -0
  244. package/dist/helpers/__tests__/semver-utils.test.js.map +1 -0
  245. package/dist/helpers/index.d.ts +3 -2
  246. package/dist/helpers/index.d.ts.map +1 -1
  247. package/dist/helpers/index.js +2 -2
  248. package/dist/helpers/index.js.map +1 -1
  249. package/dist/helpers/move-tests.d.ts +3 -3
  250. package/dist/helpers/move-tests.d.ts.map +1 -1
  251. package/dist/helpers/move-tests.js +21 -20
  252. package/dist/helpers/move-tests.js.map +1 -1
  253. package/dist/helpers/npm-registry.d.ts.map +1 -1
  254. package/dist/helpers/npm-registry.js +1 -3
  255. package/dist/helpers/npm-registry.js.map +1 -1
  256. package/dist/helpers/semver-utils.d.ts.map +1 -1
  257. package/dist/helpers/semver-utils.js +4 -3
  258. package/dist/helpers/semver-utils.js.map +1 -1
  259. package/dist/helpers/setup.d.ts.map +1 -1
  260. package/dist/helpers/setup.js +6 -4
  261. package/dist/helpers/setup.js.map +1 -1
  262. package/dist/helpers/setupLocalTesting.d.ts +31 -27
  263. package/dist/helpers/setupLocalTesting.d.ts.map +1 -1
  264. package/dist/helpers/setupLocalTesting.js +179 -180
  265. package/dist/helpers/setupLocalTesting.js.map +1 -1
  266. package/dist/helpers/testFixtures.d.ts +19 -53
  267. package/dist/helpers/testFixtures.d.ts.map +1 -1
  268. package/dist/helpers/testFixtures.js +89 -107
  269. package/dist/helpers/testFixtures.js.map +1 -1
  270. package/dist/index.d.ts +4 -2
  271. package/dist/index.d.ts.map +1 -1
  272. package/dist/index.js +6 -3
  273. package/dist/index.js.map +1 -1
  274. package/dist/node/LocalNodeManager.d.ts +9 -1
  275. package/dist/node/LocalNodeManager.d.ts.map +1 -1
  276. package/dist/node/LocalNodeManager.js +75 -58
  277. package/dist/node/LocalNodeManager.js.map +1 -1
  278. package/dist/node/__tests__/LocalNodeManager.test.d.ts +2 -0
  279. package/dist/node/__tests__/LocalNodeManager.test.d.ts.map +1 -0
  280. package/dist/node/__tests__/LocalNodeManager.test.js +349 -0
  281. package/dist/node/__tests__/LocalNodeManager.test.js.map +1 -0
  282. package/dist/runtime.d.ts +12 -15
  283. package/dist/runtime.d.ts.map +1 -1
  284. package/dist/runtime.js +26 -239
  285. package/dist/runtime.js.map +1 -1
  286. package/dist/templates/README.md +1 -1
  287. package/dist/templates/movehat.config.ts +10 -0
  288. package/dist/templates/package.json +2 -1
  289. package/dist/templates/scripts/deploy-counter.ts +46 -38
  290. package/dist/templates/tests/Counter.test.ts +39 -51
  291. package/dist/templates/types/movehat.d.ts +6 -9
  292. package/dist/types/config.d.ts +8 -0
  293. package/dist/types/config.d.ts.map +1 -1
  294. package/dist/types/fork.d.ts +7 -1
  295. package/dist/types/fork.d.ts.map +1 -1
  296. package/dist/types/harness.d.ts +166 -0
  297. package/dist/types/harness.d.ts.map +1 -0
  298. package/dist/types/harness.js +2 -0
  299. package/dist/types/harness.js.map +1 -0
  300. package/dist/types/runtime.d.ts +7 -1
  301. package/dist/types/runtime.d.ts.map +1 -1
  302. package/dist/ui/__tests__/colors.test.d.ts +2 -0
  303. package/dist/ui/__tests__/colors.test.d.ts.map +1 -0
  304. package/dist/ui/__tests__/colors.test.js +127 -0
  305. package/dist/ui/__tests__/colors.test.js.map +1 -0
  306. package/dist/ui/colors.d.ts.map +1 -1
  307. package/dist/ui/colors.js +6 -2
  308. package/dist/ui/colors.js.map +1 -1
  309. package/dist/ui/logger.d.ts +17 -0
  310. package/dist/ui/logger.d.ts.map +1 -1
  311. package/dist/ui/logger.js +22 -0
  312. package/dist/ui/logger.js.map +1 -1
  313. package/dist/ui/symbols.d.ts +1 -0
  314. package/dist/ui/symbols.d.ts.map +1 -1
  315. package/dist/ui/symbols.js +7 -1
  316. package/dist/ui/symbols.js.map +1 -1
  317. package/dist/utils/__tests__/address.test.d.ts +2 -0
  318. package/dist/utils/__tests__/address.test.d.ts.map +1 -0
  319. package/dist/utils/__tests__/address.test.js +70 -0
  320. package/dist/utils/__tests__/address.test.js.map +1 -0
  321. package/dist/utils/__tests__/childProcessAdapter.test.d.ts +2 -0
  322. package/dist/utils/__tests__/childProcessAdapter.test.d.ts.map +1 -0
  323. package/dist/utils/__tests__/childProcessAdapter.test.js +217 -0
  324. package/dist/utils/__tests__/childProcessAdapter.test.js.map +1 -0
  325. package/dist/utils/__tests__/runCli.test.d.ts +2 -0
  326. package/dist/utils/__tests__/runCli.test.d.ts.map +1 -0
  327. package/dist/utils/__tests__/runCli.test.js +187 -0
  328. package/dist/utils/__tests__/runCli.test.js.map +1 -0
  329. package/dist/utils/address.d.ts +29 -0
  330. package/dist/utils/address.d.ts.map +1 -0
  331. package/dist/utils/address.js +48 -0
  332. package/dist/utils/address.js.map +1 -0
  333. package/dist/utils/childProcessAdapter.d.ts +93 -0
  334. package/dist/utils/childProcessAdapter.d.ts.map +1 -0
  335. package/dist/utils/childProcessAdapter.js +108 -0
  336. package/dist/utils/childProcessAdapter.js.map +1 -0
  337. package/dist/utils/parseCliOutput.d.ts +20 -0
  338. package/dist/utils/parseCliOutput.d.ts.map +1 -0
  339. package/dist/utils/parseCliOutput.js +26 -0
  340. package/dist/utils/parseCliOutput.js.map +1 -0
  341. package/dist/utils/redact.d.ts +15 -0
  342. package/dist/utils/redact.d.ts.map +1 -0
  343. package/dist/utils/redact.js +24 -0
  344. package/dist/utils/redact.js.map +1 -0
  345. package/dist/utils/runCli.d.ts +24 -0
  346. package/dist/utils/runCli.d.ts.map +1 -0
  347. package/dist/utils/runCli.js +37 -0
  348. package/dist/utils/runCli.js.map +1 -0
  349. package/package.json +15 -4
  350. package/src/__tests__/deployContract.test.ts +429 -0
  351. package/src/__tests__/errors.test.ts +84 -0
  352. package/src/__tests__/fixtures/sigint-deploy-harness.ts +95 -0
  353. package/src/__tests__/fork/api.test.ts +143 -0
  354. package/src/__tests__/harness/Harness.createLive.test.ts +57 -0
  355. package/src/__tests__/harness/Harness.proxy.test.ts +111 -0
  356. package/src/__tests__/harness/_fixture.ts +131 -0
  357. package/src/__tests__/harness/codeObject.deploy.test.ts +319 -0
  358. package/src/__tests__/harness/codeObject.upgrade.test.ts +156 -0
  359. package/src/__tests__/harness/script.test.ts +245 -0
  360. package/src/__tests__/harness/view.test.ts +104 -0
  361. package/src/__tests__/runtime.test.ts +182 -0
  362. package/src/cli.ts +2 -1
  363. package/src/commands/__tests__/compile.test.ts +407 -0
  364. package/src/commands/__tests__/init.test.ts +125 -0
  365. package/src/commands/__tests__/run.test.ts +192 -0
  366. package/src/commands/__tests__/test-move.test.ts +81 -0
  367. package/src/commands/__tests__/test.test.ts +204 -0
  368. package/src/commands/__tests__/update.test.ts +223 -0
  369. package/src/commands/compile.ts +168 -32
  370. package/src/commands/fork/__tests__/create.test.ts +132 -0
  371. package/src/commands/fork/__tests__/fund.test.ts +104 -0
  372. package/src/commands/fork/__tests__/list.test.ts +139 -0
  373. package/src/commands/fork/__tests__/serve.test.ts +121 -0
  374. package/src/commands/fork/__tests__/view-resource.test.ts +101 -0
  375. package/src/commands/fork/create.ts +4 -3
  376. package/src/commands/fork/fund.ts +16 -9
  377. package/src/commands/fork/list.ts +3 -2
  378. package/src/commands/fork/serve.ts +6 -3
  379. package/src/commands/fork/view-resource.ts +11 -6
  380. package/src/commands/run.ts +54 -28
  381. package/src/commands/test-move.ts +4 -3
  382. package/src/commands/test.ts +56 -44
  383. package/src/commands/update.ts +19 -16
  384. package/src/core/AccountManager.ts +23 -22
  385. package/src/core/Publisher.ts +314 -0
  386. package/src/core/__tests__/AccountManager.test.ts +290 -0
  387. package/src/core/__tests__/config.test.ts +377 -0
  388. package/src/core/__tests__/deployments.test.ts +247 -0
  389. package/src/core/__tests__/shell.test.ts +138 -0
  390. package/src/core/config.ts +96 -12
  391. package/src/core/contract.ts +13 -7
  392. package/src/core/deployments.ts +13 -23
  393. package/src/core/movementProfile.ts +179 -0
  394. package/src/core/shell.ts +34 -14
  395. package/src/errors.ts +60 -0
  396. package/src/fork/__tests__/manager.test.ts +385 -0
  397. package/src/fork/__tests__/server.test.ts +65 -0
  398. package/src/fork/__tests__/storage.test.ts +281 -0
  399. package/src/fork/__tests__/test.test.ts +97 -0
  400. package/src/fork/api.ts +28 -14
  401. package/src/fork/manager.ts +88 -83
  402. package/src/fork/server.ts +53 -19
  403. package/src/fork/storage.ts +12 -15
  404. package/src/fork/test.ts +57 -32
  405. package/src/harness/Harness.ts +222 -0
  406. package/src/harness/codeObject.ts +384 -0
  407. package/src/harness/errors.ts +22 -0
  408. package/src/harness/index.ts +3 -0
  409. package/src/harness/proxy.ts +40 -0
  410. package/src/harness/script.ts +196 -0
  411. package/src/harness/view.ts +34 -0
  412. package/src/helpers/__tests__/semver-utils.test.ts +121 -0
  413. package/src/helpers/index.ts +2 -8
  414. package/src/helpers/move-tests.ts +27 -23
  415. package/src/helpers/npm-registry.ts +4 -3
  416. package/src/helpers/semver-utils.ts +4 -3
  417. package/src/helpers/setup.ts +6 -4
  418. package/src/helpers/setupLocalTesting.ts +218 -200
  419. package/src/helpers/testFixtures.ts +106 -118
  420. package/src/index.ts +8 -3
  421. package/src/node/LocalNodeManager.ts +87 -62
  422. package/src/node/__tests__/LocalNodeManager.test.ts +452 -0
  423. package/src/runtime.ts +28 -288
  424. package/src/templates/README.md +1 -1
  425. package/src/templates/movehat.config.ts +10 -0
  426. package/src/templates/package.json +2 -1
  427. package/src/templates/scripts/deploy-counter.ts +46 -38
  428. package/src/templates/tests/Counter.test.ts +39 -51
  429. package/src/templates/types/movehat.d.ts +6 -9
  430. package/src/types/config.ts +8 -0
  431. package/src/types/fork.ts +7 -1
  432. package/src/types/harness.ts +182 -0
  433. package/src/types/runtime.ts +11 -3
  434. package/src/ui/__tests__/colors.test.ts +156 -0
  435. package/src/ui/colors.ts +5 -2
  436. package/src/ui/logger.ts +22 -0
  437. package/src/ui/symbols.ts +7 -1
  438. package/src/utils/__tests__/address.test.ts +93 -0
  439. package/src/utils/__tests__/childProcessAdapter.test.ts +266 -0
  440. package/src/utils/__tests__/runCli.test.ts +240 -0
  441. package/src/utils/address.ts +52 -0
  442. package/src/utils/childProcessAdapter.ts +214 -0
  443. package/src/utils/parseCliOutput.ts +27 -0
  444. package/src/utils/redact.ts +24 -0
  445. package/src/utils/runCli.ts +64 -0
@@ -1,6 +1,24 @@
1
+ import { createHash } from 'node:crypto';
1
2
  import { MovementApiClient } from './api.js';
2
3
  import { ForkStorage } from './storage.js';
3
4
  import type { ForkMetadata, AccountState } from '../types/fork.js';
5
+ import { normalizeAddress } from '../utils/address.js';
6
+ import { logger } from '../ui/index.js';
7
+
8
+ /**
9
+ * Derive a deterministic 32-byte hex placeholder for the `authentication_key`
10
+ * of a fork-funded account. The real auth_key is `sha3_256(public_key || 0x00)`
11
+ * for Ed25519; the fork has no public key material, so we hash the address
12
+ * itself. This is NOT a real auth key — downstream code must not treat it as
13
+ * trustworthy key material. Distinguishable from the address by construction
14
+ * (#63 — prior code used `address.padEnd(66, '0')` which was a no-op since
15
+ * normalized addresses are already 66 chars).
16
+ */
17
+ function forkAuthKeyPlaceholder(normalizedAddress: string): string {
18
+ const stripped = normalizedAddress.startsWith('0x') ? normalizedAddress.slice(2) : normalizedAddress;
19
+ const digest = createHash('sha3-256').update(stripped, 'hex').digest('hex');
20
+ return `0x${digest}`;
21
+ }
4
22
 
5
23
  /**
6
24
  * Manager for fork operations
@@ -11,24 +29,53 @@ export class ForkManager {
11
29
  private apiClient: MovementApiClient | null = null;
12
30
  private metadata: ForkMetadata | null = null;
13
31
 
32
+ /**
33
+ * Optional API key sent as `Authorization: Bearer <key>` on every
34
+ * outgoing Movement API request. Not persisted to disk via
35
+ * {@link ForkMetadata} (keys stay in process memory). For the
36
+ * load-then-set pattern, call {@link setApiKey} after `load()`.
37
+ */
38
+ private apiKey?: string;
39
+
14
40
  constructor(forkPath: string) {
15
41
  this.storage = new ForkStorage(forkPath);
16
42
  }
17
43
 
18
44
  /**
19
- * Initialize a new fork from a network
45
+ * Set or update the API key used for upstream Movement API requests.
46
+ * Reconstructs the internal `MovementApiClient` if one exists.
47
+ */
48
+ setApiKey(apiKey: string | undefined): void {
49
+ if (apiKey === undefined) {
50
+ delete this.apiKey;
51
+ } else {
52
+ this.apiKey = apiKey;
53
+ }
54
+ if (this.apiClient && this.metadata) {
55
+ this.apiClient = new MovementApiClient(this.metadata.nodeUrl, this.apiKey);
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Initialize a new fork from a network.
61
+ *
62
+ * @param nodeUrl - Upstream JSON-RPC base URL.
63
+ * @param networkName - Logical network label (defaults to `'custom'`).
64
+ * @param apiKey - Optional API key for `Authorization: Bearer` header.
20
65
  */
21
- async initialize(nodeUrl: string, networkName: string = 'custom'): Promise<void> {
22
- // Create API client
23
- this.apiClient = new MovementApiClient(nodeUrl);
66
+ async initialize(
67
+ nodeUrl: string,
68
+ networkName: string = 'custom',
69
+ apiKey?: string
70
+ ): Promise<void> {
71
+ if (apiKey !== undefined) this.apiKey = apiKey;
72
+
73
+ this.apiClient = new MovementApiClient(nodeUrl, this.apiKey);
24
74
 
25
- // Fetch network info
26
75
  const ledgerInfo = await this.apiClient.getLedgerInfo();
27
76
 
28
- // Create fork structure
29
77
  this.storage.initialize();
30
78
 
31
- // Save metadata
32
79
  this.metadata = {
33
80
  network: networkName,
34
81
  nodeUrl,
@@ -46,7 +93,9 @@ export class ForkManager {
46
93
  }
47
94
 
48
95
  /**
49
- * Load an existing fork
96
+ * Load an existing fork. The API key is NOT persisted to disk —
97
+ * callers needing authenticated upstream reads after `load()` must
98
+ * call {@link setApiKey} explicitly.
50
99
  */
51
100
  load(): void {
52
101
  if (!this.storage.exists()) {
@@ -54,12 +103,9 @@ export class ForkManager {
54
103
  }
55
104
 
56
105
  this.metadata = this.storage.loadMetadata();
57
- this.apiClient = new MovementApiClient(this.metadata.nodeUrl);
106
+ this.apiClient = new MovementApiClient(this.metadata.nodeUrl, this.apiKey);
58
107
  }
59
108
 
60
- /**
61
- * Get fork metadata
62
- */
63
109
  getMetadata(): ForkMetadata {
64
110
  if (!this.metadata) {
65
111
  this.metadata = this.storage.loadMetadata();
@@ -67,18 +113,12 @@ export class ForkManager {
67
113
  return this.metadata;
68
114
  }
69
115
 
70
- /**
71
- * Get account state (with lazy loading)
72
- */
73
116
  async getAccount(address: string): Promise<AccountState> {
74
- // Normalize address
75
- const normalizedAddress = this.normalizeAddress(address);
117
+ const normalizedAddress = normalizeAddress(address);
76
118
 
77
- // Check cache first
78
119
  let accountState = this.storage.getAccount(normalizedAddress);
79
120
 
80
121
  if (!accountState) {
81
- // Fetch from network
82
122
  if (!this.apiClient) {
83
123
  throw new Error('Fork not initialized. Call initialize() or load() first.');
84
124
  }
@@ -91,7 +131,6 @@ export class ForkManager {
91
131
  authenticationKey: accountData.authentication_key,
92
132
  };
93
133
 
94
- // Cache it
95
134
  this.storage.saveAccount(normalizedAddress, accountState);
96
135
  console.log(` ✓ Cached account ${normalizedAddress}`);
97
136
  }
@@ -99,17 +138,12 @@ export class ForkManager {
99
138
  return accountState;
100
139
  }
101
140
 
102
- /**
103
- * Get a specific resource (with lazy loading)
104
- */
105
141
  async getResource(address: string, resourceType: string): Promise<any> {
106
- const normalizedAddress = this.normalizeAddress(address);
142
+ const normalizedAddress = normalizeAddress(address);
107
143
 
108
- // Check cache first
109
144
  let resource = this.storage.getResource(normalizedAddress, resourceType);
110
145
 
111
146
  if (!resource) {
112
- // Fetch from network
113
147
  if (!this.apiClient) {
114
148
  throw new Error('Fork not initialized. Call initialize() or load() first.');
115
149
  }
@@ -120,11 +154,11 @@ export class ForkManager {
120
154
  const resourceData = await this.apiClient.getAccountResource(normalizedAddress, resourceType);
121
155
  resource = resourceData.data;
122
156
 
123
- // Cache it
124
157
  this.storage.saveResource(normalizedAddress, resourceType, resource);
125
158
  console.log(` ✓ Cached resource ${resourceType}`);
126
- } catch (error: any) {
127
- if (error.message.includes('404')) {
159
+ } catch (error) {
160
+ const msg = error instanceof Error ? error.message : String(error);
161
+ if (msg.includes('404')) {
128
162
  throw new Error(`Resource ${resourceType} not found for account ${normalizedAddress}`);
129
163
  }
130
164
  throw error;
@@ -134,16 +168,11 @@ export class ForkManager {
134
168
  return resource;
135
169
  }
136
170
 
137
- /**
138
- * Get all resources for an account (with lazy loading)
139
- */
140
171
  async getAllResources(address: string): Promise<Record<string, any>> {
141
- const normalizedAddress = this.normalizeAddress(address);
172
+ const normalizedAddress = normalizeAddress(address);
142
173
 
143
- // Check if we have any cached resources
144
174
  let resources = this.storage.getAllResources(normalizedAddress);
145
175
 
146
- // If no cached resources, fetch all from network
147
176
  if (Object.keys(resources).length === 0) {
148
177
  if (!this.apiClient) {
149
178
  throw new Error('Fork not initialized. Call initialize() or load() first.');
@@ -157,7 +186,6 @@ export class ForkManager {
157
186
  resources[resource.type] = resource.data;
158
187
  }
159
188
 
160
- // Cache them
161
189
  this.storage.saveAllResources(normalizedAddress, resources);
162
190
  console.log(` ✓ Cached ${Object.keys(resources).length} resources`);
163
191
  }
@@ -165,33 +193,32 @@ export class ForkManager {
165
193
  return resources;
166
194
  }
167
195
 
168
- /**
169
- * Set a resource value (for testing/mocking)
170
- */
171
- async setResource(address: string, resourceType: string, data: any): Promise<void> {
172
- const normalizedAddress = this.normalizeAddress(address);
196
+ async setResource(address: string, resourceType: string, data: unknown): Promise<void> {
197
+ const normalizedAddress = normalizeAddress(address);
173
198
  this.storage.saveResource(normalizedAddress, resourceType, data);
174
199
  console.log(` ✓ Updated resource ${resourceType} for ${normalizedAddress}`);
175
200
  }
176
201
 
177
- /**
178
- * Fund an account with coins (adds to existing balance)
179
- */
202
+ /** Adds to the existing balance rather than replacing it. */
180
203
  async fundAccount(address: string, amount: number, coinType: string = '0x1::aptos_coin::AptosCoin'): Promise<void> {
181
- const normalizedAddress = this.normalizeAddress(address);
204
+ const normalizedAddress = normalizeAddress(address);
182
205
  const resourceType = `0x1::coin::CoinStore<${coinType}>`;
183
206
 
184
- // Try to get existing coin store
207
+ // Try to get existing coin store. The coin store is a CoinStore<T>
208
+ // resource whose `data` is Movement-side untyped JSON; we shape it
209
+ // locally as a structural object with `coin.value: string`.
210
+ // any: full CoinStore schema lives at the Movement REST boundary —
211
+ // proper validation deferred to the boundary-validation follow-up of #57.
185
212
  let coinStore: any;
186
213
  try {
187
214
  coinStore = await this.getResource(normalizedAddress, resourceType);
188
- } catch (error: any) {
215
+ } catch (error) {
189
216
  // Only catch "not found" errors, rethrow others (network, API, etc.)
190
- if (!error.message || !error.message.includes('not found')) {
217
+ const msg = error instanceof Error ? error.message : String(error);
218
+ if (!msg.includes('not found')) {
191
219
  throw error;
192
220
  }
193
221
 
194
- // If doesn't exist, create new one
195
222
  coinStore = {
196
223
  coin: { value: '0' },
197
224
  deposit_events: {
@@ -216,20 +243,17 @@ export class ForkManager {
216
243
  };
217
244
  }
218
245
 
219
- // Add to existing balance (instead of replacing it)
220
246
  const currentBalance = BigInt(coinStore.coin.value ?? '0');
221
247
  const newBalance = currentBalance + BigInt(amount);
222
248
  coinStore.coin.value = newBalance.toString();
223
249
 
224
- // Save
225
250
  await this.setResource(normalizedAddress, resourceType, coinStore);
226
251
 
227
- // Also ensure account exists
228
252
  let account = this.storage.getAccount(normalizedAddress);
229
253
  if (!account) {
230
254
  account = {
231
255
  sequenceNumber: '0',
232
- authenticationKey: normalizedAddress.padEnd(66, '0'),
256
+ authenticationKey: forkAuthKeyPlaceholder(normalizedAddress),
233
257
  };
234
258
  this.storage.saveAccount(normalizedAddress, account);
235
259
  }
@@ -237,27 +261,6 @@ export class ForkManager {
237
261
  console.log(` ✓ Funded ${normalizedAddress} with ${amount} coins`);
238
262
  }
239
263
 
240
- /**
241
- * Normalize address format
242
- */
243
- private normalizeAddress(address: string): string {
244
- let normalized = address.toLowerCase();
245
-
246
- if (!normalized.startsWith('0x')) {
247
- normalized = `0x${normalized}`;
248
- }
249
-
250
- // Pad to 66 characters (0x + 64 hex chars)
251
- if (normalized.length < 66) {
252
- normalized = '0x' + normalized.slice(2).padStart(64, '0');
253
- }
254
-
255
- return normalized;
256
- }
257
-
258
- /**
259
- * List all accounts in the fork
260
- */
261
264
  listAccounts(): string[] {
262
265
  return this.storage.listAccounts();
263
266
  }
@@ -267,7 +270,7 @@ export class ForkManager {
267
270
  *
268
271
  * @param addresses Array of addresses to fund
269
272
  * @param amount Amount of coins per account
270
- * @param coinType Coin type (defaults to AptosCoin)
273
+ * @param coinType Coin type (defaults to the chain's native coin)
271
274
  *
272
275
  * @example
273
276
  * await forkManager.fundMultipleAccounts(
@@ -280,13 +283,15 @@ export class ForkManager {
280
283
  amount: number,
281
284
  coinType: string = '0x1::aptos_coin::AptosCoin'
282
285
  ): Promise<void> {
283
- console.log(`\n💰 Funding ${addresses.length} accounts with ${amount} coins each...`);
286
+ logger.newline();
287
+ logger.step(`Funding ${addresses.length} accounts with ${amount} coins each...`);
284
288
 
285
289
  for (const address of addresses) {
286
290
  await this.fundAccount(address, amount, coinType);
287
291
  }
288
292
 
289
- console.log(`✓ All accounts funded successfully\n`);
293
+ logger.success("All accounts funded successfully");
294
+ logger.newline();
290
295
  }
291
296
 
292
297
  /**
@@ -297,13 +302,15 @@ export class ForkManager {
297
302
  * await forkManager.resetState();
298
303
  */
299
304
  async resetState(): Promise<void> {
300
- console.log(`\n🔄 Resetting fork state...`);
305
+ logger.newline();
306
+ logger.step("Resetting fork state...");
301
307
 
302
308
  // Clear all accounts and resources from storage
303
309
  this.storage.clearAccounts();
304
310
  this.storage.clearResources();
305
311
 
306
- console.log(`✓ Fork state reset to initial snapshot\n`);
312
+ logger.success("Fork state reset to initial snapshot");
313
+ logger.newline();
307
314
  }
308
315
 
309
316
  /**
@@ -317,16 +324,14 @@ export class ForkManager {
317
324
  * const account = await forkManager.getOrCreateAccount("0x123...");
318
325
  */
319
326
  async getOrCreateAccount(address: string): Promise<AccountState> {
320
- const normalizedAddress = this.normalizeAddress(address);
327
+ const normalizedAddress = normalizeAddress(address);
321
328
 
322
- // Try to get existing account
323
329
  try {
324
330
  return await this.getAccount(normalizedAddress);
325
331
  } catch (error) {
326
- // If account doesn't exist, create a minimal one
327
332
  const newAccount: AccountState = {
328
333
  sequenceNumber: '0',
329
- authenticationKey: normalizedAddress.padEnd(66, '0'),
334
+ authenticationKey: forkAuthKeyPlaceholder(normalizedAddress),
330
335
  };
331
336
 
332
337
  this.storage.saveAccount(normalizedAddress, newAccount);
@@ -3,17 +3,24 @@ import { URL } from 'url';
3
3
  import { ForkManager } from './manager.js';
4
4
 
5
5
  /**
6
- * Fork Server - Serves fork data via Movement/Aptos RPC API
6
+ * Fork Server - Serves fork data via Movement L1 RPC API
7
7
  * Emulates a Movement L1 node using local fork storage
8
8
  */
9
9
  export class ForkServer {
10
10
  private server: http.Server | null = null;
11
11
  private forkManager: ForkManager;
12
12
  private port: number;
13
+ private host: string;
13
14
 
14
- constructor(forkPath: string, port: number = 8080) {
15
+ /**
16
+ * @param host Interface to bind. Defaults to `127.0.0.1` so cached fork
17
+ * state (which may include sensitive resources) is not exposed on the LAN.
18
+ * Pass `'0.0.0.0'` only if you intentionally need to expose the server.
19
+ */
20
+ constructor(forkPath: string, port: number = 8080, host: string = '127.0.0.1') {
15
21
  this.forkManager = new ForkManager(forkPath);
16
22
  this.port = port;
23
+ this.host = host;
17
24
  }
18
25
 
19
26
  /**
@@ -52,6 +59,12 @@ export class ForkServer {
52
59
  });
53
60
  });
54
61
 
62
+ // Capture the just-assigned server into a non-null local so we don't
63
+ // have to repeatedly assert `this.server!` (which TS forces because
64
+ // `http.createServer` returns an unrelated narrow that the field
65
+ // declaration doesn't track).
66
+ const server = this.server;
67
+
55
68
  return new Promise((resolve, reject) => {
56
69
  // Handle server errors (port in use, permission denied, etc.)
57
70
  const onError = (error: NodeJS.ErrnoException) => {
@@ -65,14 +78,26 @@ export class ForkServer {
65
78
  };
66
79
 
67
80
  // Listen for errors during startup
68
- this.server!.once('error', onError);
81
+ server.once('error', onError);
69
82
 
70
- this.server!.listen(this.port, () => {
83
+ server.listen(this.port, this.host, () => {
71
84
  // Remove error listener after successful start
72
- this.server!.removeListener('error', onError);
73
-
74
- console.log(`\nFork Server listening on http://localhost:${this.port}`);
75
- console.log(` Ledger Info: http://localhost:${this.port}/v1/`);
85
+ server.removeListener('error', onError);
86
+
87
+ // IPv6 literals must be wrapped in brackets in URLs (RFC 3986).
88
+ const isIpv6 = this.host.includes(':');
89
+ const displayHost =
90
+ this.host === '0.0.0.0'
91
+ ? 'localhost'
92
+ : isIpv6
93
+ ? `[${this.host}]`
94
+ : this.host;
95
+ console.log(`\nFork Server listening on http://${displayHost}:${this.port}`);
96
+ console.log(` Bound interface: ${this.host}`);
97
+ console.log(` Ledger Info: http://${displayHost}:${this.port}/v1/`);
98
+ if (this.host === '0.0.0.0') {
99
+ console.warn(` Server is bound to 0.0.0.0 — fork state is reachable from the LAN.`);
100
+ }
76
101
  console.log(`\nPress Ctrl+C to stop`);
77
102
  resolve();
78
103
  });
@@ -143,11 +168,15 @@ export class ForkServer {
143
168
  const resourceIndex = parts.indexOf('resource') + 1;
144
169
  const address = parts[accountIndex];
145
170
  const resourceType = decodeURIComponent(parts.slice(resourceIndex).join('/'));
171
+ if (!address) {
172
+ this.send404(res, 'Malformed resource path', 'malformed_path');
173
+ return;
174
+ }
146
175
  await this.handleGetResource(address, resourceType, res);
147
176
  } else {
148
177
  // Use regex capture for resources endpoint
149
178
  const resourcesMatch = pathname.match(/^\/v1\/accounts\/(0x[a-fA-F0-9]{1,64})\/resources$/);
150
- if (resourcesMatch) {
179
+ if (resourcesMatch && resourcesMatch[1]) {
151
180
  const address = resourcesMatch[1];
152
181
  await this.handleGetResources(address, res);
153
182
  } else {
@@ -156,7 +185,7 @@ export class ForkServer {
156
185
  this.send404(res, `Endpoint not found: ${safePath}`, 'endpoint_not_found');
157
186
  }
158
187
  }
159
- } catch (error: any) {
188
+ } catch (error) {
160
189
  // Log full error server-side for diagnostics
161
190
  console.error('Error handling request:', error);
162
191
 
@@ -208,8 +237,9 @@ export class ForkServer {
208
237
  sequence_number: account.sequenceNumber,
209
238
  authentication_key: account.authenticationKey
210
239
  });
211
- } catch (error: any) {
212
- if (error.message.includes('not found')) {
240
+ } catch (error) {
241
+ const msg = error instanceof Error ? error.message : String(error);
242
+ if (msg.includes('not found')) {
213
243
  this.send404(res, `Account not found: ${address}`);
214
244
  } else {
215
245
  throw error;
@@ -232,8 +262,9 @@ export class ForkServer {
232
262
  type: resourceType,
233
263
  data: resource
234
264
  });
235
- } catch (error: any) {
236
- if (error.message.includes('not found')) {
265
+ } catch (error) {
266
+ const msg = error instanceof Error ? error.message : String(error);
267
+ if (msg.includes('not found')) {
237
268
  this.send404(res, `Resource not found: ${resourceType}`, 'resource_not_found');
238
269
  } else {
239
270
  throw error;
@@ -251,15 +282,16 @@ export class ForkServer {
251
282
  try {
252
283
  const resources = await this.forkManager.getAllResources(address);
253
284
 
254
- // Convert to array format expected by Aptos API
285
+ // Convert to array format expected by the Movement L1 API
255
286
  const resourcesArray = Object.entries(resources).map(([type, data]) => ({
256
287
  type,
257
288
  data
258
289
  }));
259
290
 
260
291
  this.sendJSON(res, 200, resourcesArray);
261
- } catch (error: any) {
262
- if (error.message.includes('not found')) {
292
+ } catch (error) {
293
+ const msg = error instanceof Error ? error.message : String(error);
294
+ if (msg.includes('not found')) {
263
295
  this.send404(res, `Account not found: ${address}`);
264
296
  } else {
265
297
  throw error;
@@ -268,12 +300,14 @@ export class ForkServer {
268
300
  }
269
301
 
270
302
  /**
271
- * Send JSON response
303
+ * Send JSON response.
304
+ * unknown: arbitrary JSON-serializable payload; structural shape varies by
305
+ * endpoint (account metadata, resource arrays, error envelopes).
272
306
  */
273
307
  private sendJSON(
274
308
  res: http.ServerResponse,
275
309
  status: number,
276
- data: any,
310
+ data: unknown,
277
311
  extraHeaders: Record<string, string> = {}
278
312
  ): void {
279
313
  const body = JSON.stringify(data, null, 2);
@@ -1,25 +1,22 @@
1
1
  import { existsSync, mkdirSync, readFileSync, writeFileSync, readdirSync, unlinkSync } from 'fs';
2
2
  import { join } from 'path';
3
3
  import type { ForkMetadata, AccountState } from '../types/fork.js';
4
+ import { isHexAddress } from '../utils/address.js';
4
5
 
5
6
  /**
6
- * Sanitize address to create a safe filename
7
- * Prevents path traversal by encoding the address
7
+ * Sanitize address to create a safe filename. Validates the address through
8
+ * the shared `isHexAddress` helper (length 1–64 hex chars, optional `0x`),
9
+ * then rebuilds a canonical `0x…` form. The trailing path-separator check is
10
+ * defense-in-depth: unreachable after `isHexAddress`, but cheap to keep.
8
11
  */
9
12
  function sanitizeAddressForFilename(address: string): string {
10
- // Remove any path separators and normalize
11
- const normalized = address.toLowerCase().replace(/^0x/, '');
12
-
13
- // Validate that it's a valid hex string
14
- if (!/^[0-9a-f]+$/.test(normalized)) {
13
+ if (!isHexAddress(address)) {
15
14
  throw new Error(`Invalid address format: ${address}. Expected hexadecimal string.`);
16
15
  }
17
16
 
18
- // Encode to prevent any path traversal
19
- // Use the normalized hex string directly as it's safe
17
+ const normalized = address.toLowerCase().replace(/^0x/, '');
20
18
  const safe = `0x${normalized}`;
21
19
 
22
- // Validate no path separators in result
23
20
  if (safe.includes('/') || safe.includes('\\') || safe.includes('..')) {
24
21
  throw new Error(`Address contains invalid characters: ${address}`);
25
22
  }
@@ -141,7 +138,7 @@ export class ForkStorage {
141
138
  /**
142
139
  * Get resource for an account
143
140
  */
144
- getResource(address: string, resourceType: string): any | null {
141
+ getResource(address: string, resourceType: string): unknown | null {
145
142
  const resourceFilePath = this.getResourceFilePath(address);
146
143
 
147
144
  if (!existsSync(resourceFilePath)) {
@@ -155,7 +152,7 @@ export class ForkStorage {
155
152
  /**
156
153
  * Get all resources for an account
157
154
  */
158
- getAllResources(address: string): Record<string, any> {
155
+ getAllResources(address: string): Record<string, unknown> {
159
156
  const resourceFilePath = this.getResourceFilePath(address);
160
157
 
161
158
  if (!existsSync(resourceFilePath)) {
@@ -168,7 +165,7 @@ export class ForkStorage {
168
165
  /**
169
166
  * Save resource for an account
170
167
  */
171
- saveResource(address: string, resourceType: string, data: any): void {
168
+ saveResource(address: string, resourceType: string, data: unknown): void {
172
169
  const resourceFilePath = this.getResourceFilePath(address);
173
170
 
174
171
  // Ensure resources directory exists
@@ -177,7 +174,7 @@ export class ForkStorage {
177
174
  mkdirSync(resourcesDir, { recursive: true });
178
175
  }
179
176
 
180
- let resources: Record<string, any> = {};
177
+ let resources: Record<string, unknown> = {};
181
178
  if (existsSync(resourceFilePath)) {
182
179
  resources = JSON.parse(readFileSync(resourceFilePath, 'utf-8'));
183
180
  }
@@ -189,7 +186,7 @@ export class ForkStorage {
189
186
  /**
190
187
  * Save all resources for an account
191
188
  */
192
- saveAllResources(address: string, resources: Record<string, any>): void {
189
+ saveAllResources(address: string, resources: Record<string, unknown>): void {
193
190
  const resourceFilePath = this.getResourceFilePath(address);
194
191
 
195
192
  // Ensure resources directory exists