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.
- package/README.md +2 -2
- package/dist/__tests__/deployContract.test.d.ts +2 -0
- package/dist/__tests__/deployContract.test.d.ts.map +1 -0
- package/dist/__tests__/deployContract.test.js +368 -0
- package/dist/__tests__/deployContract.test.js.map +1 -0
- package/dist/__tests__/errors.test.d.ts +2 -0
- package/dist/__tests__/errors.test.d.ts.map +1 -0
- package/dist/__tests__/errors.test.js +46 -0
- package/dist/__tests__/errors.test.js.map +1 -0
- package/dist/__tests__/fixtures/sigint-deploy-harness.d.ts +24 -0
- package/dist/__tests__/fixtures/sigint-deploy-harness.d.ts.map +1 -0
- package/dist/__tests__/fixtures/sigint-deploy-harness.js +82 -0
- package/dist/__tests__/fixtures/sigint-deploy-harness.js.map +1 -0
- package/dist/__tests__/fork/api.test.d.ts +2 -0
- package/dist/__tests__/fork/api.test.d.ts.map +1 -0
- package/dist/__tests__/fork/api.test.js +110 -0
- package/dist/__tests__/fork/api.test.js.map +1 -0
- package/dist/__tests__/harness/Harness.createLive.test.d.ts +2 -0
- package/dist/__tests__/harness/Harness.createLive.test.d.ts.map +1 -0
- package/dist/__tests__/harness/Harness.createLive.test.js +53 -0
- package/dist/__tests__/harness/Harness.createLive.test.js.map +1 -0
- package/dist/__tests__/harness/Harness.proxy.test.d.ts +2 -0
- package/dist/__tests__/harness/Harness.proxy.test.d.ts.map +1 -0
- package/dist/__tests__/harness/Harness.proxy.test.js +93 -0
- package/dist/__tests__/harness/Harness.proxy.test.js.map +1 -0
- package/dist/__tests__/harness/_fixture.d.ts +54 -0
- package/dist/__tests__/harness/_fixture.d.ts.map +1 -0
- package/dist/__tests__/harness/_fixture.js +69 -0
- package/dist/__tests__/harness/_fixture.js.map +1 -0
- package/dist/__tests__/harness/codeObject.deploy.test.d.ts +2 -0
- package/dist/__tests__/harness/codeObject.deploy.test.d.ts.map +1 -0
- package/dist/__tests__/harness/codeObject.deploy.test.js +288 -0
- package/dist/__tests__/harness/codeObject.deploy.test.js.map +1 -0
- package/dist/__tests__/harness/codeObject.upgrade.test.d.ts +2 -0
- package/dist/__tests__/harness/codeObject.upgrade.test.d.ts.map +1 -0
- package/dist/__tests__/harness/codeObject.upgrade.test.js +138 -0
- package/dist/__tests__/harness/codeObject.upgrade.test.js.map +1 -0
- package/dist/__tests__/harness/script.test.d.ts +2 -0
- package/dist/__tests__/harness/script.test.d.ts.map +1 -0
- package/dist/__tests__/harness/script.test.js +219 -0
- package/dist/__tests__/harness/script.test.js.map +1 -0
- package/dist/__tests__/harness/view.test.d.ts +2 -0
- package/dist/__tests__/harness/view.test.d.ts.map +1 -0
- package/dist/__tests__/harness/view.test.js +92 -0
- package/dist/__tests__/harness/view.test.js.map +1 -0
- package/dist/__tests__/runtime.test.d.ts +2 -0
- package/dist/__tests__/runtime.test.d.ts.map +1 -0
- package/dist/__tests__/runtime.test.js +141 -0
- package/dist/__tests__/runtime.test.js.map +1 -0
- package/dist/cli.js +2 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/__tests__/compile.test.d.ts +2 -0
- package/dist/commands/__tests__/compile.test.d.ts.map +1 -0
- package/dist/commands/__tests__/compile.test.js +351 -0
- package/dist/commands/__tests__/compile.test.js.map +1 -0
- package/dist/commands/__tests__/init.test.d.ts +2 -0
- package/dist/commands/__tests__/init.test.d.ts.map +1 -0
- package/dist/commands/__tests__/init.test.js +101 -0
- package/dist/commands/__tests__/init.test.js.map +1 -0
- package/dist/commands/__tests__/run.test.d.ts +2 -0
- package/dist/commands/__tests__/run.test.d.ts.map +1 -0
- package/dist/commands/__tests__/run.test.js +166 -0
- package/dist/commands/__tests__/run.test.js.map +1 -0
- package/dist/commands/__tests__/test-move.test.d.ts +2 -0
- package/dist/commands/__tests__/test-move.test.d.ts.map +1 -0
- package/dist/commands/__tests__/test-move.test.js +59 -0
- package/dist/commands/__tests__/test-move.test.js.map +1 -0
- package/dist/commands/__tests__/test.test.d.ts +2 -0
- package/dist/commands/__tests__/test.test.d.ts.map +1 -0
- package/dist/commands/__tests__/test.test.js +168 -0
- package/dist/commands/__tests__/test.test.js.map +1 -0
- package/dist/commands/__tests__/update.test.d.ts +2 -0
- package/dist/commands/__tests__/update.test.d.ts.map +1 -0
- package/dist/commands/__tests__/update.test.js +176 -0
- package/dist/commands/__tests__/update.test.js.map +1 -0
- package/dist/commands/compile.d.ts +7 -1
- package/dist/commands/compile.d.ts.map +1 -1
- package/dist/commands/compile.js +150 -33
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/fork/__tests__/create.test.d.ts +2 -0
- package/dist/commands/fork/__tests__/create.test.d.ts.map +1 -0
- package/dist/commands/fork/__tests__/create.test.js +108 -0
- package/dist/commands/fork/__tests__/create.test.js.map +1 -0
- package/dist/commands/fork/__tests__/fund.test.d.ts +2 -0
- package/dist/commands/fork/__tests__/fund.test.d.ts.map +1 -0
- package/dist/commands/fork/__tests__/fund.test.js +72 -0
- package/dist/commands/fork/__tests__/fund.test.js.map +1 -0
- package/dist/commands/fork/__tests__/list.test.d.ts +2 -0
- package/dist/commands/fork/__tests__/list.test.d.ts.map +1 -0
- package/dist/commands/fork/__tests__/list.test.js +119 -0
- package/dist/commands/fork/__tests__/list.test.js.map +1 -0
- package/dist/commands/fork/__tests__/serve.test.d.ts +2 -0
- package/dist/commands/fork/__tests__/serve.test.d.ts.map +1 -0
- package/dist/commands/fork/__tests__/serve.test.js +97 -0
- package/dist/commands/fork/__tests__/serve.test.js.map +1 -0
- package/dist/commands/fork/__tests__/view-resource.test.d.ts +2 -0
- package/dist/commands/fork/__tests__/view-resource.test.d.ts.map +1 -0
- package/dist/commands/fork/__tests__/view-resource.test.js +77 -0
- package/dist/commands/fork/__tests__/view-resource.test.js.map +1 -0
- package/dist/commands/fork/create.d.ts +1 -1
- package/dist/commands/fork/create.d.ts.map +1 -1
- package/dist/commands/fork/create.js +3 -2
- package/dist/commands/fork/create.js.map +1 -1
- package/dist/commands/fork/fund.d.ts.map +1 -1
- package/dist/commands/fork/fund.js +15 -8
- package/dist/commands/fork/fund.js.map +1 -1
- package/dist/commands/fork/list.d.ts.map +1 -1
- package/dist/commands/fork/list.js +2 -1
- package/dist/commands/fork/list.js.map +1 -1
- package/dist/commands/fork/serve.d.ts +1 -0
- package/dist/commands/fork/serve.d.ts.map +1 -1
- package/dist/commands/fork/serve.js +4 -2
- package/dist/commands/fork/serve.js.map +1 -1
- package/dist/commands/fork/view-resource.d.ts.map +1 -1
- package/dist/commands/fork/view-resource.js +10 -5
- package/dist/commands/fork/view-resource.js.map +1 -1
- package/dist/commands/run.d.ts +15 -0
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +50 -27
- package/dist/commands/run.js.map +1 -1
- package/dist/commands/test-move.d.ts.map +1 -1
- package/dist/commands/test-move.js +3 -2
- package/dist/commands/test-move.js.map +1 -1
- package/dist/commands/test.js +52 -46
- package/dist/commands/test.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +15 -13
- package/dist/commands/update.js.map +1 -1
- package/dist/core/AccountManager.d.ts +1 -1
- package/dist/core/AccountManager.d.ts.map +1 -1
- package/dist/core/AccountManager.js +20 -7
- package/dist/core/AccountManager.js.map +1 -1
- package/dist/core/Publisher.d.ts +31 -0
- package/dist/core/Publisher.d.ts.map +1 -0
- package/dist/core/Publisher.js +248 -0
- package/dist/core/Publisher.js.map +1 -0
- package/dist/core/__tests__/AccountManager.test.d.ts +2 -0
- package/dist/core/__tests__/AccountManager.test.d.ts.map +1 -0
- package/dist/core/__tests__/AccountManager.test.js +239 -0
- package/dist/core/__tests__/AccountManager.test.js.map +1 -0
- package/dist/core/__tests__/config.test.d.ts +2 -0
- package/dist/core/__tests__/config.test.d.ts.map +1 -0
- package/dist/core/__tests__/config.test.js +311 -0
- package/dist/core/__tests__/config.test.js.map +1 -0
- package/dist/core/__tests__/deployments.test.d.ts +2 -0
- package/dist/core/__tests__/deployments.test.d.ts.map +1 -0
- package/dist/core/__tests__/deployments.test.js +201 -0
- package/dist/core/__tests__/deployments.test.js.map +1 -0
- package/dist/core/__tests__/shell.test.d.ts +2 -0
- package/dist/core/__tests__/shell.test.d.ts.map +1 -0
- package/dist/core/__tests__/shell.test.js +107 -0
- package/dist/core/__tests__/shell.test.js.map +1 -0
- package/dist/core/config.d.ts +13 -1
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +80 -11
- package/dist/core/config.js.map +1 -1
- package/dist/core/contract.d.ts +1 -1
- package/dist/core/contract.d.ts.map +1 -1
- package/dist/core/contract.js +15 -4
- package/dist/core/contract.js.map +1 -1
- package/dist/core/deployments.d.ts +2 -2
- package/dist/core/deployments.d.ts.map +1 -1
- package/dist/core/deployments.js +8 -6
- package/dist/core/deployments.js.map +1 -1
- package/dist/core/movementProfile.d.ts +34 -0
- package/dist/core/movementProfile.d.ts.map +1 -0
- package/dist/core/movementProfile.js +150 -0
- package/dist/core/movementProfile.js.map +1 -0
- package/dist/core/shell.d.ts +23 -7
- package/dist/core/shell.d.ts.map +1 -1
- package/dist/core/shell.js +32 -14
- package/dist/core/shell.js.map +1 -1
- package/dist/errors.d.ts +35 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +54 -0
- package/dist/errors.js.map +1 -1
- package/dist/fork/__tests__/manager.test.d.ts +2 -0
- package/dist/fork/__tests__/manager.test.d.ts.map +1 -0
- package/dist/fork/__tests__/manager.test.js +309 -0
- package/dist/fork/__tests__/manager.test.js.map +1 -0
- package/dist/fork/__tests__/server.test.d.ts +2 -0
- package/dist/fork/__tests__/server.test.d.ts.map +1 -0
- package/dist/fork/__tests__/server.test.js +54 -0
- package/dist/fork/__tests__/server.test.js.map +1 -0
- package/dist/fork/__tests__/storage.test.d.ts +2 -0
- package/dist/fork/__tests__/storage.test.d.ts.map +1 -0
- package/dist/fork/__tests__/storage.test.js +222 -0
- package/dist/fork/__tests__/storage.test.js.map +1 -0
- package/dist/fork/__tests__/test.test.d.ts +2 -0
- package/dist/fork/__tests__/test.test.d.ts.map +1 -0
- package/dist/fork/__tests__/test.test.js +81 -0
- package/dist/fork/__tests__/test.test.js.map +1 -0
- package/dist/fork/api.d.ts +14 -3
- package/dist/fork/api.d.ts.map +1 -1
- package/dist/fork/api.js +25 -14
- package/dist/fork/api.js.map +1 -1
- package/dist/fork/manager.d.ts +23 -9
- package/dist/fork/manager.d.ts.map +1 -1
- package/dist/fork/manager.js +79 -36
- package/dist/fork/manager.js.map +1 -1
- package/dist/fork/server.d.ts +11 -3
- package/dist/fork/server.d.ts.map +1 -1
- package/dist/fork/server.js +45 -13
- package/dist/fork/server.js.map +1 -1
- package/dist/fork/storage.d.ts +4 -4
- package/dist/fork/storage.d.ts.map +1 -1
- package/dist/fork/storage.js +7 -9
- package/dist/fork/storage.js.map +1 -1
- package/dist/fork/test.d.ts +13 -4
- package/dist/fork/test.d.ts.map +1 -1
- package/dist/fork/test.js +36 -27
- package/dist/fork/test.js.map +1 -1
- package/dist/harness/Harness.d.ts +124 -0
- package/dist/harness/Harness.d.ts.map +1 -0
- package/dist/harness/Harness.js +193 -0
- package/dist/harness/Harness.js.map +1 -0
- package/dist/harness/codeObject.d.ts +31 -0
- package/dist/harness/codeObject.d.ts.map +1 -0
- package/dist/harness/codeObject.js +271 -0
- package/dist/harness/codeObject.js.map +1 -0
- package/dist/harness/errors.d.ts +14 -0
- package/dist/harness/errors.d.ts.map +1 -0
- package/dist/harness/errors.js +22 -0
- package/dist/harness/errors.js.map +1 -0
- package/dist/harness/index.d.ts +4 -0
- package/dist/harness/index.d.ts.map +1 -0
- package/dist/harness/index.js +3 -0
- package/dist/harness/index.js.map +1 -0
- package/dist/harness/proxy.d.ts +7 -0
- package/dist/harness/proxy.d.ts.map +1 -0
- package/dist/harness/proxy.js +36 -0
- package/dist/harness/proxy.js.map +1 -0
- package/dist/harness/script.d.ts +21 -0
- package/dist/harness/script.d.ts.map +1 -0
- package/dist/harness/script.js +155 -0
- package/dist/harness/script.js.map +1 -0
- package/dist/harness/view.d.ts +22 -0
- package/dist/harness/view.d.ts.map +1 -0
- package/dist/harness/view.js +28 -0
- package/dist/harness/view.js.map +1 -0
- package/dist/helpers/__tests__/semver-utils.test.d.ts +2 -0
- package/dist/helpers/__tests__/semver-utils.test.d.ts.map +1 -0
- package/dist/helpers/__tests__/semver-utils.test.js +103 -0
- package/dist/helpers/__tests__/semver-utils.test.js.map +1 -0
- package/dist/helpers/index.d.ts +3 -2
- package/dist/helpers/index.d.ts.map +1 -1
- package/dist/helpers/index.js +2 -2
- package/dist/helpers/index.js.map +1 -1
- package/dist/helpers/move-tests.d.ts +3 -3
- package/dist/helpers/move-tests.d.ts.map +1 -1
- package/dist/helpers/move-tests.js +21 -20
- package/dist/helpers/move-tests.js.map +1 -1
- package/dist/helpers/npm-registry.d.ts.map +1 -1
- package/dist/helpers/npm-registry.js +1 -3
- package/dist/helpers/npm-registry.js.map +1 -1
- package/dist/helpers/semver-utils.d.ts.map +1 -1
- package/dist/helpers/semver-utils.js +4 -3
- package/dist/helpers/semver-utils.js.map +1 -1
- package/dist/helpers/setup.d.ts.map +1 -1
- package/dist/helpers/setup.js +6 -4
- package/dist/helpers/setup.js.map +1 -1
- package/dist/helpers/setupLocalTesting.d.ts +32 -27
- package/dist/helpers/setupLocalTesting.d.ts.map +1 -1
- package/dist/helpers/setupLocalTesting.js +179 -180
- package/dist/helpers/setupLocalTesting.js.map +1 -1
- package/dist/helpers/testFixtures.d.ts +19 -53
- package/dist/helpers/testFixtures.d.ts.map +1 -1
- package/dist/helpers/testFixtures.js +89 -107
- package/dist/helpers/testFixtures.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -3
- package/dist/index.js.map +1 -1
- package/dist/node/LocalNodeManager.d.ts +9 -1
- package/dist/node/LocalNodeManager.d.ts.map +1 -1
- package/dist/node/LocalNodeManager.js +75 -58
- package/dist/node/LocalNodeManager.js.map +1 -1
- package/dist/node/__tests__/LocalNodeManager.test.d.ts +2 -0
- package/dist/node/__tests__/LocalNodeManager.test.d.ts.map +1 -0
- package/dist/node/__tests__/LocalNodeManager.test.js +349 -0
- package/dist/node/__tests__/LocalNodeManager.test.js.map +1 -0
- package/dist/runtime.d.ts +12 -15
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +28 -239
- package/dist/runtime.js.map +1 -1
- package/dist/templates/README.md +1 -1
- package/dist/templates/movehat.config.ts +10 -0
- package/dist/templates/package.json +2 -1
- package/dist/templates/scripts/deploy-counter.ts +46 -38
- package/dist/templates/tests/Counter.test.ts +39 -51
- package/dist/templates/types/movehat.d.ts +6 -9
- package/dist/types/config.d.ts +8 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/fork.d.ts +7 -1
- package/dist/types/fork.d.ts.map +1 -1
- package/dist/types/harness.d.ts +166 -0
- package/dist/types/harness.d.ts.map +1 -0
- package/dist/types/harness.js +2 -0
- package/dist/types/harness.js.map +1 -0
- package/dist/types/runtime.d.ts +7 -1
- package/dist/types/runtime.d.ts.map +1 -1
- package/dist/ui/__tests__/colors.test.d.ts +2 -0
- package/dist/ui/__tests__/colors.test.d.ts.map +1 -0
- package/dist/ui/__tests__/colors.test.js +127 -0
- package/dist/ui/__tests__/colors.test.js.map +1 -0
- package/dist/ui/colors.d.ts.map +1 -1
- package/dist/ui/colors.js +6 -2
- package/dist/ui/colors.js.map +1 -1
- package/dist/ui/logger.d.ts +17 -0
- package/dist/ui/logger.d.ts.map +1 -1
- package/dist/ui/logger.js +22 -0
- package/dist/ui/logger.js.map +1 -1
- package/dist/ui/symbols.d.ts +1 -0
- package/dist/ui/symbols.d.ts.map +1 -1
- package/dist/ui/symbols.js +7 -1
- package/dist/ui/symbols.js.map +1 -1
- package/dist/utils/__tests__/address.test.d.ts +2 -0
- package/dist/utils/__tests__/address.test.d.ts.map +1 -0
- package/dist/utils/__tests__/address.test.js +70 -0
- package/dist/utils/__tests__/address.test.js.map +1 -0
- package/dist/utils/__tests__/childProcessAdapter.test.d.ts +2 -0
- package/dist/utils/__tests__/childProcessAdapter.test.d.ts.map +1 -0
- package/dist/utils/__tests__/childProcessAdapter.test.js +217 -0
- package/dist/utils/__tests__/childProcessAdapter.test.js.map +1 -0
- package/dist/utils/__tests__/runCli.test.d.ts +2 -0
- package/dist/utils/__tests__/runCli.test.d.ts.map +1 -0
- package/dist/utils/__tests__/runCli.test.js +187 -0
- package/dist/utils/__tests__/runCli.test.js.map +1 -0
- package/dist/utils/address.d.ts +33 -0
- package/dist/utils/address.d.ts.map +1 -0
- package/dist/utils/address.js +52 -0
- package/dist/utils/address.js.map +1 -0
- package/dist/utils/childProcessAdapter.d.ts +93 -0
- package/dist/utils/childProcessAdapter.d.ts.map +1 -0
- package/dist/utils/childProcessAdapter.js +109 -0
- package/dist/utils/childProcessAdapter.js.map +1 -0
- package/dist/utils/parseCliOutput.d.ts +20 -0
- package/dist/utils/parseCliOutput.d.ts.map +1 -0
- package/dist/utils/parseCliOutput.js +26 -0
- package/dist/utils/parseCliOutput.js.map +1 -0
- package/dist/utils/redact.d.ts +15 -0
- package/dist/utils/redact.d.ts.map +1 -0
- package/dist/utils/redact.js +24 -0
- package/dist/utils/redact.js.map +1 -0
- package/dist/utils/runCli.d.ts +24 -0
- package/dist/utils/runCli.d.ts.map +1 -0
- package/dist/utils/runCli.js +37 -0
- package/dist/utils/runCli.js.map +1 -0
- package/package.json +14 -4
- package/src/__tests__/deployContract.test.ts +429 -0
- package/src/__tests__/errors.test.ts +84 -0
- package/src/__tests__/fixtures/sigint-deploy-harness.ts +95 -0
- package/src/__tests__/fork/api.test.ts +143 -0
- package/src/__tests__/harness/Harness.createLive.test.ts +57 -0
- package/src/__tests__/harness/Harness.proxy.test.ts +115 -0
- package/src/__tests__/harness/_fixture.ts +131 -0
- package/src/__tests__/harness/codeObject.deploy.test.ts +319 -0
- package/src/__tests__/harness/codeObject.upgrade.test.ts +156 -0
- package/src/__tests__/harness/script.test.ts +245 -0
- package/src/__tests__/harness/view.test.ts +104 -0
- package/src/__tests__/runtime.test.ts +182 -0
- package/src/cli.ts +2 -1
- package/src/commands/__tests__/compile.test.ts +407 -0
- package/src/commands/__tests__/init.test.ts +125 -0
- package/src/commands/__tests__/run.test.ts +192 -0
- package/src/commands/__tests__/test-move.test.ts +81 -0
- package/src/commands/__tests__/test.test.ts +204 -0
- package/src/commands/__tests__/update.test.ts +223 -0
- package/src/commands/compile.ts +168 -32
- package/src/commands/fork/__tests__/create.test.ts +132 -0
- package/src/commands/fork/__tests__/fund.test.ts +104 -0
- package/src/commands/fork/__tests__/list.test.ts +139 -0
- package/src/commands/fork/__tests__/serve.test.ts +121 -0
- package/src/commands/fork/__tests__/view-resource.test.ts +101 -0
- package/src/commands/fork/create.ts +4 -3
- package/src/commands/fork/fund.ts +16 -9
- package/src/commands/fork/list.ts +3 -2
- package/src/commands/fork/serve.ts +6 -3
- package/src/commands/fork/view-resource.ts +11 -6
- package/src/commands/run.ts +54 -28
- package/src/commands/test-move.ts +4 -3
- package/src/commands/test.ts +56 -44
- package/src/commands/update.ts +19 -16
- package/src/core/AccountManager.ts +23 -10
- package/src/core/Publisher.ts +322 -0
- package/src/core/__tests__/AccountManager.test.ts +290 -0
- package/src/core/__tests__/config.test.ts +377 -0
- package/src/core/__tests__/deployments.test.ts +247 -0
- package/src/core/__tests__/shell.test.ts +138 -0
- package/src/core/config.ts +96 -12
- package/src/core/contract.ts +13 -4
- package/src/core/deployments.ts +13 -11
- package/src/core/movementProfile.ts +179 -0
- package/src/core/shell.ts +34 -14
- package/src/errors.ts +60 -0
- package/src/fork/__tests__/manager.test.ts +385 -0
- package/src/fork/__tests__/server.test.ts +65 -0
- package/src/fork/__tests__/storage.test.ts +281 -0
- package/src/fork/__tests__/test.test.ts +97 -0
- package/src/fork/api.ts +28 -14
- package/src/fork/manager.ts +88 -43
- package/src/fork/server.ts +53 -19
- package/src/fork/storage.ts +12 -15
- package/src/fork/test.ts +58 -32
- package/src/harness/Harness.ts +228 -0
- package/src/harness/codeObject.ts +388 -0
- package/src/harness/errors.ts +22 -0
- package/src/harness/index.ts +3 -0
- package/src/harness/proxy.ts +40 -0
- package/src/harness/script.ts +196 -0
- package/src/harness/view.ts +34 -0
- package/src/helpers/__tests__/semver-utils.test.ts +121 -0
- package/src/helpers/index.ts +2 -8
- package/src/helpers/move-tests.ts +27 -23
- package/src/helpers/npm-registry.ts +4 -3
- package/src/helpers/semver-utils.ts +4 -3
- package/src/helpers/setup.ts +6 -4
- package/src/helpers/setupLocalTesting.ts +219 -200
- package/src/helpers/testFixtures.ts +106 -118
- package/src/index.ts +9 -3
- package/src/node/LocalNodeManager.ts +87 -62
- package/src/node/__tests__/LocalNodeManager.test.ts +452 -0
- package/src/runtime.ts +30 -288
- package/src/templates/README.md +1 -1
- package/src/templates/movehat.config.ts +10 -0
- package/src/templates/package.json +2 -1
- package/src/templates/scripts/deploy-counter.ts +46 -38
- package/src/templates/tests/Counter.test.ts +39 -51
- package/src/templates/types/movehat.d.ts +6 -9
- package/src/types/config.ts +8 -0
- package/src/types/fork.ts +7 -1
- package/src/types/harness.ts +182 -0
- package/src/types/runtime.ts +11 -3
- package/src/ui/__tests__/colors.test.ts +156 -0
- package/src/ui/colors.ts +5 -2
- package/src/ui/logger.ts +22 -0
- package/src/ui/symbols.ts +7 -1
- package/src/utils/__tests__/address.test.ts +93 -0
- package/src/utils/__tests__/childProcessAdapter.test.ts +266 -0
- package/src/utils/__tests__/runCli.test.ts +240 -0
- package/src/utils/address.ts +56 -0
- package/src/utils/childProcessAdapter.ts +215 -0
- package/src/utils/parseCliOutput.ts +27 -0
- package/src/utils/redact.ts +24 -0
- package/src/utils/runCli.ts +64 -0
package/src/fork/manager.ts
CHANGED
|
@@ -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
|
-
*
|
|
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(
|
|
22
|
-
|
|
23
|
-
|
|
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 =
|
|
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 =
|
|
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
|
|
127
|
-
|
|
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 =
|
|
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:
|
|
172
|
-
const normalizedAddress =
|
|
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 =
|
|
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
|
|
246
|
+
} catch (error) {
|
|
189
247
|
// Only catch "not found" errors, rethrow others (network, API, etc.)
|
|
190
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
|
374
|
+
authenticationKey: forkAuthKeyPlaceholder(normalizedAddress),
|
|
330
375
|
};
|
|
331
376
|
|
|
332
377
|
this.storage.saveAccount(normalizedAddress, newAccount);
|
package/src/fork/server.ts
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
81
|
+
server.once('error', onError);
|
|
69
82
|
|
|
70
|
-
|
|
83
|
+
server.listen(this.port, this.host, () => {
|
|
71
84
|
// Remove error listener after successful start
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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
|
|
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
|
|
212
|
-
|
|
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
|
|
236
|
-
|
|
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
|
|
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
|
|
262
|
-
|
|
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:
|
|
310
|
+
data: unknown,
|
|
277
311
|
extraHeaders: Record<string, string> = {}
|
|
278
312
|
): void {
|
|
279
313
|
const body = JSON.stringify(data, null, 2);
|
package/src/fork/storage.ts
CHANGED
|
@@ -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
|
-
*
|
|
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
|
-
|
|
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
|
-
|
|
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):
|
|
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,
|
|
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:
|
|
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,
|
|
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,
|
|
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
|
-
|
|
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
|
-
//
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
|
64
|
-
|
|
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
|
-
//
|
|
129
|
-
const { stdout } = await
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
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
|
|
149
|
-
|
|
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:
|
|
168
|
-
): Promise<{ fork:
|
|
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 {
|