movehat 0.1.9 → 0.2.0

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 +2 -2
  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 +93 -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 -1
  130. package/dist/core/AccountManager.d.ts.map +1 -1
  131. package/dist/core/AccountManager.js +20 -7
  132. package/dist/core/AccountManager.js.map +1 -1
  133. package/dist/core/Publisher.d.ts +31 -0
  134. package/dist/core/Publisher.d.ts.map +1 -0
  135. package/dist/core/Publisher.js +248 -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 -1
  158. package/dist/core/contract.d.ts.map +1 -1
  159. package/dist/core/contract.js +15 -4
  160. package/dist/core/contract.js.map +1 -1
  161. package/dist/core/deployments.d.ts +2 -2
  162. package/dist/core/deployments.d.ts.map +1 -1
  163. package/dist/core/deployments.js +8 -6
  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 -9
  198. package/dist/fork/manager.d.ts.map +1 -1
  199. package/dist/fork/manager.js +79 -36
  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 +13 -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 +124 -0
  214. package/dist/harness/Harness.d.ts.map +1 -0
  215. package/dist/harness/Harness.js +193 -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 +271 -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 +32 -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 +7 -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 +28 -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 +33 -0
  330. package/dist/utils/address.d.ts.map +1 -0
  331. package/dist/utils/address.js +52 -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 +109 -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 +14 -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 +115 -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 -10
  385. package/src/core/Publisher.ts +322 -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 -4
  392. package/src/core/deployments.ts +13 -11
  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 -43
  402. package/src/fork/server.ts +53 -19
  403. package/src/fork/storage.ts +12 -15
  404. package/src/fork/test.ts +58 -32
  405. package/src/harness/Harness.ts +228 -0
  406. package/src/harness/codeObject.ts +388 -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 +219 -200
  419. package/src/helpers/testFixtures.ts +106 -118
  420. package/src/index.ts +9 -3
  421. package/src/node/LocalNodeManager.ts +87 -62
  422. package/src/node/__tests__/LocalNodeManager.test.ts +452 -0
  423. package/src/runtime.ts +30 -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 +56 -0
  442. package/src/utils/childProcessAdapter.ts +215 -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,16 +29,49 @@ 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
+ // Create API client (with optional Authorization header)
74
+ this.apiClient = new MovementApiClient(nodeUrl, this.apiKey);
24
75
 
25
76
  // Fetch network info
26
77
  const ledgerInfo = await this.apiClient.getLedgerInfo();
@@ -46,7 +97,9 @@ export class ForkManager {
46
97
  }
47
98
 
48
99
  /**
49
- * Load an existing fork
100
+ * Load an existing fork. The API key is NOT persisted to disk —
101
+ * callers needing authenticated upstream reads after `load()` must
102
+ * call {@link setApiKey} explicitly.
50
103
  */
51
104
  load(): void {
52
105
  if (!this.storage.exists()) {
@@ -54,7 +107,7 @@ export class ForkManager {
54
107
  }
55
108
 
56
109
  this.metadata = this.storage.loadMetadata();
57
- this.apiClient = new MovementApiClient(this.metadata.nodeUrl);
110
+ this.apiClient = new MovementApiClient(this.metadata.nodeUrl, this.apiKey);
58
111
  }
59
112
 
60
113
  /**
@@ -72,7 +125,7 @@ export class ForkManager {
72
125
  */
73
126
  async getAccount(address: string): Promise<AccountState> {
74
127
  // Normalize address
75
- const normalizedAddress = this.normalizeAddress(address);
128
+ const normalizedAddress = normalizeAddress(address);
76
129
 
77
130
  // Check cache first
78
131
  let accountState = this.storage.getAccount(normalizedAddress);
@@ -103,7 +156,7 @@ export class ForkManager {
103
156
  * Get a specific resource (with lazy loading)
104
157
  */
105
158
  async getResource(address: string, resourceType: string): Promise<any> {
106
- const normalizedAddress = this.normalizeAddress(address);
159
+ const normalizedAddress = normalizeAddress(address);
107
160
 
108
161
  // Check cache first
109
162
  let resource = this.storage.getResource(normalizedAddress, resourceType);
@@ -123,8 +176,9 @@ export class ForkManager {
123
176
  // Cache it
124
177
  this.storage.saveResource(normalizedAddress, resourceType, resource);
125
178
  console.log(` ✓ Cached resource ${resourceType}`);
126
- } catch (error: any) {
127
- if (error.message.includes('404')) {
179
+ } catch (error) {
180
+ const msg = error instanceof Error ? error.message : String(error);
181
+ if (msg.includes('404')) {
128
182
  throw new Error(`Resource ${resourceType} not found for account ${normalizedAddress}`);
129
183
  }
130
184
  throw error;
@@ -138,7 +192,7 @@ export class ForkManager {
138
192
  * Get all resources for an account (with lazy loading)
139
193
  */
140
194
  async getAllResources(address: string): Promise<Record<string, any>> {
141
- const normalizedAddress = this.normalizeAddress(address);
195
+ const normalizedAddress = normalizeAddress(address);
142
196
 
143
197
  // Check if we have any cached resources
144
198
  let resources = this.storage.getAllResources(normalizedAddress);
@@ -168,8 +222,8 @@ export class ForkManager {
168
222
  /**
169
223
  * Set a resource value (for testing/mocking)
170
224
  */
171
- async setResource(address: string, resourceType: string, data: any): Promise<void> {
172
- const normalizedAddress = this.normalizeAddress(address);
225
+ async setResource(address: string, resourceType: string, data: unknown): Promise<void> {
226
+ const normalizedAddress = normalizeAddress(address);
173
227
  this.storage.saveResource(normalizedAddress, resourceType, data);
174
228
  console.log(` ✓ Updated resource ${resourceType} for ${normalizedAddress}`);
175
229
  }
@@ -178,16 +232,21 @@ export class ForkManager {
178
232
  * Fund an account with coins (adds to existing balance)
179
233
  */
180
234
  async fundAccount(address: string, amount: number, coinType: string = '0x1::aptos_coin::AptosCoin'): Promise<void> {
181
- const normalizedAddress = this.normalizeAddress(address);
235
+ const normalizedAddress = normalizeAddress(address);
182
236
  const resourceType = `0x1::coin::CoinStore<${coinType}>`;
183
237
 
184
- // Try to get existing coin store
238
+ // Try to get existing coin store. The coin store is a CoinStore<T>
239
+ // resource whose `data` is Movement-side untyped JSON; we shape it
240
+ // locally as a structural object with `coin.value: string`.
241
+ // any: full CoinStore schema lives at the Movement REST boundary —
242
+ // proper validation deferred to the boundary-validation follow-up of #57.
185
243
  let coinStore: any;
186
244
  try {
187
245
  coinStore = await this.getResource(normalizedAddress, resourceType);
188
- } catch (error: any) {
246
+ } catch (error) {
189
247
  // Only catch "not found" errors, rethrow others (network, API, etc.)
190
- if (!error.message || !error.message.includes('not found')) {
248
+ const msg = error instanceof Error ? error.message : String(error);
249
+ if (!msg.includes('not found')) {
191
250
  throw error;
192
251
  }
193
252
 
@@ -229,7 +288,7 @@ export class ForkManager {
229
288
  if (!account) {
230
289
  account = {
231
290
  sequenceNumber: '0',
232
- authenticationKey: normalizedAddress.padEnd(66, '0'),
291
+ authenticationKey: forkAuthKeyPlaceholder(normalizedAddress),
233
292
  };
234
293
  this.storage.saveAccount(normalizedAddress, account);
235
294
  }
@@ -237,24 +296,6 @@ export class ForkManager {
237
296
  console.log(` ✓ Funded ${normalizedAddress} with ${amount} coins`);
238
297
  }
239
298
 
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
299
  /**
259
300
  * List all accounts in the fork
260
301
  */
@@ -267,7 +308,7 @@ export class ForkManager {
267
308
  *
268
309
  * @param addresses Array of addresses to fund
269
310
  * @param amount Amount of coins per account
270
- * @param coinType Coin type (defaults to AptosCoin)
311
+ * @param coinType Coin type (defaults to the chain's native coin)
271
312
  *
272
313
  * @example
273
314
  * await forkManager.fundMultipleAccounts(
@@ -280,13 +321,15 @@ export class ForkManager {
280
321
  amount: number,
281
322
  coinType: string = '0x1::aptos_coin::AptosCoin'
282
323
  ): Promise<void> {
283
- console.log(`\n💰 Funding ${addresses.length} accounts with ${amount} coins each...`);
324
+ logger.newline();
325
+ logger.step(`Funding ${addresses.length} accounts with ${amount} coins each...`);
284
326
 
285
327
  for (const address of addresses) {
286
328
  await this.fundAccount(address, amount, coinType);
287
329
  }
288
330
 
289
- console.log(`✓ All accounts funded successfully\n`);
331
+ logger.success("All accounts funded successfully");
332
+ logger.newline();
290
333
  }
291
334
 
292
335
  /**
@@ -297,13 +340,15 @@ export class ForkManager {
297
340
  * await forkManager.resetState();
298
341
  */
299
342
  async resetState(): Promise<void> {
300
- console.log(`\n🔄 Resetting fork state...`);
343
+ logger.newline();
344
+ logger.step("Resetting fork state...");
301
345
 
302
346
  // Clear all accounts and resources from storage
303
347
  this.storage.clearAccounts();
304
348
  this.storage.clearResources();
305
349
 
306
- console.log(`✓ Fork state reset to initial snapshot\n`);
350
+ logger.success("Fork state reset to initial snapshot");
351
+ logger.newline();
307
352
  }
308
353
 
309
354
  /**
@@ -317,7 +362,7 @@ export class ForkManager {
317
362
  * const account = await forkManager.getOrCreateAccount("0x123...");
318
363
  */
319
364
  async getOrCreateAccount(address: string): Promise<AccountState> {
320
- const normalizedAddress = this.normalizeAddress(address);
365
+ const normalizedAddress = normalizeAddress(address);
321
366
 
322
367
  // Try to get existing account
323
368
  try {
@@ -326,7 +371,7 @@ export class ForkManager {
326
371
  // If account doesn't exist, create a minimal one
327
372
  const newAccount: AccountState = {
328
373
  sequenceNumber: '0',
329
- authenticationKey: normalizedAddress.padEnd(66, '0'),
374
+ authenticationKey: forkAuthKeyPlaceholder(normalizedAddress),
330
375
  };
331
376
 
332
377
  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
package/src/fork/test.ts CHANGED
@@ -1,13 +1,17 @@
1
- import { execFile } from 'child_process';
2
- import { promisify } from 'util';
3
1
  import { join } from 'path';
4
2
  import { existsSync } from 'fs';
5
-
6
- const execFileAsync = promisify(execFile);
3
+ import { runCli } from '../utils/runCli.js';
4
+ import type { ChildProcessAdapter } from '../utils/childProcessAdapter.js';
7
5
 
8
6
  export interface SnapshotOptions {
9
7
  path?: string;
10
8
  name?: string;
9
+ /**
10
+ * Override the child-process adapter. Test-only — production callers
11
+ * leave this undefined so the default spawn-based adapter is used.
12
+ * Mirrors the M1.3c pattern on `runtime.deployContract`.
13
+ */
14
+ adapter?: ChildProcessAdapter;
11
15
  }
12
16
 
13
17
  export interface ForkInfo {
@@ -40,15 +44,22 @@ export async function snapshot(options: SnapshotOptions = {}): Promise<string> {
40
44
  console.log(`📸 Creating snapshot: ${name}...`);
41
45
 
42
46
  try {
43
- // Initialize fork/snapshot using aptos CLI
44
- // Use execFile with argument array to prevent command injection
45
- const { stdout, stderr } = await execFileAsync('aptos', [
46
- 'move',
47
- 'sim',
48
- 'init',
49
- '--path',
50
- snapshotPath
51
- ]);
47
+ // Initialize fork/snapshot using aptos CLI.
48
+ // runCli uses spawn-with-args under the hood (no shell), preventing
49
+ // command injection. Pass throwOnNonZeroExit:false so the exitCode is
50
+ // observable below — the stderr/dir defenses are belt-and-suspenders
51
+ // on top of the exitCode check.
52
+ const { stdout, stderr, exitCode } = await runCli(
53
+ {
54
+ command: 'aptos',
55
+ args: ['move', 'sim', 'init', '--path', snapshotPath],
56
+ },
57
+ { throwOnNonZeroExit: false, adapter: options.adapter }
58
+ );
59
+
60
+ if (exitCode !== 0) {
61
+ throw new Error(stderr || `fork snapshot init failed with exit code ${exitCode}`);
62
+ }
52
63
 
53
64
  if (stderr && !stderr.includes('Success')) {
54
65
  throw new Error(stderr);
@@ -60,8 +71,9 @@ export async function snapshot(options: SnapshotOptions = {}): Promise<string> {
60
71
 
61
72
  console.log(` ✓ Snapshot created at ${snapshotPath}`);
62
73
  return snapshotPath;
63
- } catch (error: any) {
64
- throw new Error(`Failed to create snapshot: ${error.message}`);
74
+ } catch (error) {
75
+ const msg = error instanceof Error ? error.message : String(error);
76
+ throw new Error(`Failed to create snapshot: ${msg}`);
65
77
  }
66
78
  }
67
79
 
@@ -122,21 +134,34 @@ export async function getForkInfo(path: string): Promise<ForkInfo> {
122
134
  export async function viewForkResource(
123
135
  sessionPath: string,
124
136
  account: string,
125
- resourceType: string
137
+ resourceType: string,
138
+ options: { adapter?: ChildProcessAdapter } = {}
126
139
  ): Promise<any> {
127
140
  try {
128
- // Use execFile with argument array to prevent command injection
129
- const { stdout } = await execFileAsync('aptos', [
130
- 'move',
131
- 'sim',
132
- 'view-resource',
133
- '--session',
134
- sessionPath,
135
- '--account',
136
- account,
137
- '--resource',
138
- resourceType
139
- ]);
141
+ // runCli uses spawn-with-args (no shell) to prevent command injection.
142
+ const { stdout, stderr, exitCode } = await runCli(
143
+ {
144
+ command: 'aptos',
145
+ args: [
146
+ 'move',
147
+ 'sim',
148
+ 'view-resource',
149
+ '--session',
150
+ sessionPath,
151
+ '--account',
152
+ account,
153
+ '--resource',
154
+ resourceType,
155
+ ],
156
+ },
157
+ { throwOnNonZeroExit: false, adapter: options.adapter }
158
+ );
159
+
160
+ if (exitCode !== 0) {
161
+ throw new Error(
162
+ stderr || `fork view-resource failed with exit code ${exitCode}`
163
+ );
164
+ }
140
165
 
141
166
  const result = JSON.parse(stdout);
142
167
 
@@ -145,8 +170,9 @@ export async function viewForkResource(
145
170
  }
146
171
 
147
172
  return result.Result;
148
- } catch (error: any) {
149
- throw new Error(`Failed to view resource: ${error.message}`);
173
+ } catch (error) {
174
+ const msg = error instanceof Error ? error.message : String(error);
175
+ throw new Error(`Failed to view resource: ${msg}`);
150
176
  }
151
177
  }
152
178
 
@@ -164,8 +190,8 @@ export async function compareForkState(
164
190
  forkPath: string,
165
191
  account: string,
166
192
  resourceType: string,
167
- currentValue: any
168
- ): Promise<{ fork: any; current: any; changed: boolean }> {
193
+ currentValue: unknown
194
+ ): Promise<{ fork: unknown; current: unknown; changed: boolean }> {
169
195
  const forkValue = await viewForkResource(forkPath, account, resourceType);
170
196
 
171
197
  return {