movehat 0.1.9 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +132 -279
- 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 +89 -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 -4
- package/dist/core/AccountManager.d.ts.map +1 -1
- package/dist/core/AccountManager.js +20 -12
- package/dist/core/AccountManager.js.map +1 -1
- package/dist/core/Publisher.d.ts +26 -0
- package/dist/core/Publisher.d.ts.map +1 -0
- package/dist/core/Publisher.js +240 -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 -4
- package/dist/core/contract.d.ts.map +1 -1
- package/dist/core/contract.js +15 -7
- package/dist/core/contract.js.map +1 -1
- package/dist/core/deployments.d.ts +2 -8
- package/dist/core/deployments.d.ts.map +1 -1
- package/dist/core/deployments.js +8 -18
- 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 -29
- package/dist/fork/manager.d.ts.map +1 -1
- package/dist/fork/manager.js +79 -76
- 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 +12 -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 +118 -0
- package/dist/harness/Harness.d.ts.map +1 -0
- package/dist/harness/Harness.js +187 -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 +267 -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 +31 -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 +6 -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 +26 -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 +29 -0
- package/dist/utils/address.d.ts.map +1 -0
- package/dist/utils/address.js +48 -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 +108 -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 +15 -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 +111 -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 -22
- package/src/core/Publisher.ts +314 -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 -7
- package/src/core/deployments.ts +13 -23
- 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 -83
- package/src/fork/server.ts +53 -19
- package/src/fork/storage.ts +12 -15
- package/src/fork/test.ts +57 -32
- package/src/harness/Harness.ts +222 -0
- package/src/harness/codeObject.ts +384 -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 +218 -200
- package/src/helpers/testFixtures.ts +106 -118
- package/src/index.ts +8 -3
- package/src/node/LocalNodeManager.ts +87 -62
- package/src/node/__tests__/LocalNodeManager.test.ts +452 -0
- package/src/runtime.ts +28 -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 +52 -0
- package/src/utils/childProcessAdapter.ts +214 -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,24 +29,53 @@ export class ForkManager {
|
|
|
11
29
|
private apiClient: MovementApiClient | null = null;
|
|
12
30
|
private metadata: ForkMetadata | null = null;
|
|
13
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Optional API key sent as `Authorization: Bearer <key>` on every
|
|
34
|
+
* outgoing Movement API request. Not persisted to disk via
|
|
35
|
+
* {@link ForkMetadata} (keys stay in process memory). For the
|
|
36
|
+
* load-then-set pattern, call {@link setApiKey} after `load()`.
|
|
37
|
+
*/
|
|
38
|
+
private apiKey?: string;
|
|
39
|
+
|
|
14
40
|
constructor(forkPath: string) {
|
|
15
41
|
this.storage = new ForkStorage(forkPath);
|
|
16
42
|
}
|
|
17
43
|
|
|
18
44
|
/**
|
|
19
|
-
*
|
|
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
|
+
this.apiClient = new MovementApiClient(nodeUrl, this.apiKey);
|
|
24
74
|
|
|
25
|
-
// Fetch network info
|
|
26
75
|
const ledgerInfo = await this.apiClient.getLedgerInfo();
|
|
27
76
|
|
|
28
|
-
// Create fork structure
|
|
29
77
|
this.storage.initialize();
|
|
30
78
|
|
|
31
|
-
// Save metadata
|
|
32
79
|
this.metadata = {
|
|
33
80
|
network: networkName,
|
|
34
81
|
nodeUrl,
|
|
@@ -46,7 +93,9 @@ export class ForkManager {
|
|
|
46
93
|
}
|
|
47
94
|
|
|
48
95
|
/**
|
|
49
|
-
* Load an existing fork
|
|
96
|
+
* Load an existing fork. The API key is NOT persisted to disk —
|
|
97
|
+
* callers needing authenticated upstream reads after `load()` must
|
|
98
|
+
* call {@link setApiKey} explicitly.
|
|
50
99
|
*/
|
|
51
100
|
load(): void {
|
|
52
101
|
if (!this.storage.exists()) {
|
|
@@ -54,12 +103,9 @@ export class ForkManager {
|
|
|
54
103
|
}
|
|
55
104
|
|
|
56
105
|
this.metadata = this.storage.loadMetadata();
|
|
57
|
-
this.apiClient = new MovementApiClient(this.metadata.nodeUrl);
|
|
106
|
+
this.apiClient = new MovementApiClient(this.metadata.nodeUrl, this.apiKey);
|
|
58
107
|
}
|
|
59
108
|
|
|
60
|
-
/**
|
|
61
|
-
* Get fork metadata
|
|
62
|
-
*/
|
|
63
109
|
getMetadata(): ForkMetadata {
|
|
64
110
|
if (!this.metadata) {
|
|
65
111
|
this.metadata = this.storage.loadMetadata();
|
|
@@ -67,18 +113,12 @@ export class ForkManager {
|
|
|
67
113
|
return this.metadata;
|
|
68
114
|
}
|
|
69
115
|
|
|
70
|
-
/**
|
|
71
|
-
* Get account state (with lazy loading)
|
|
72
|
-
*/
|
|
73
116
|
async getAccount(address: string): Promise<AccountState> {
|
|
74
|
-
|
|
75
|
-
const normalizedAddress = this.normalizeAddress(address);
|
|
117
|
+
const normalizedAddress = normalizeAddress(address);
|
|
76
118
|
|
|
77
|
-
// Check cache first
|
|
78
119
|
let accountState = this.storage.getAccount(normalizedAddress);
|
|
79
120
|
|
|
80
121
|
if (!accountState) {
|
|
81
|
-
// Fetch from network
|
|
82
122
|
if (!this.apiClient) {
|
|
83
123
|
throw new Error('Fork not initialized. Call initialize() or load() first.');
|
|
84
124
|
}
|
|
@@ -91,7 +131,6 @@ export class ForkManager {
|
|
|
91
131
|
authenticationKey: accountData.authentication_key,
|
|
92
132
|
};
|
|
93
133
|
|
|
94
|
-
// Cache it
|
|
95
134
|
this.storage.saveAccount(normalizedAddress, accountState);
|
|
96
135
|
console.log(` ✓ Cached account ${normalizedAddress}`);
|
|
97
136
|
}
|
|
@@ -99,17 +138,12 @@ export class ForkManager {
|
|
|
99
138
|
return accountState;
|
|
100
139
|
}
|
|
101
140
|
|
|
102
|
-
/**
|
|
103
|
-
* Get a specific resource (with lazy loading)
|
|
104
|
-
*/
|
|
105
141
|
async getResource(address: string, resourceType: string): Promise<any> {
|
|
106
|
-
const normalizedAddress =
|
|
142
|
+
const normalizedAddress = normalizeAddress(address);
|
|
107
143
|
|
|
108
|
-
// Check cache first
|
|
109
144
|
let resource = this.storage.getResource(normalizedAddress, resourceType);
|
|
110
145
|
|
|
111
146
|
if (!resource) {
|
|
112
|
-
// Fetch from network
|
|
113
147
|
if (!this.apiClient) {
|
|
114
148
|
throw new Error('Fork not initialized. Call initialize() or load() first.');
|
|
115
149
|
}
|
|
@@ -120,11 +154,11 @@ export class ForkManager {
|
|
|
120
154
|
const resourceData = await this.apiClient.getAccountResource(normalizedAddress, resourceType);
|
|
121
155
|
resource = resourceData.data;
|
|
122
156
|
|
|
123
|
-
// Cache it
|
|
124
157
|
this.storage.saveResource(normalizedAddress, resourceType, resource);
|
|
125
158
|
console.log(` ✓ Cached resource ${resourceType}`);
|
|
126
|
-
} catch (error
|
|
127
|
-
|
|
159
|
+
} catch (error) {
|
|
160
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
161
|
+
if (msg.includes('404')) {
|
|
128
162
|
throw new Error(`Resource ${resourceType} not found for account ${normalizedAddress}`);
|
|
129
163
|
}
|
|
130
164
|
throw error;
|
|
@@ -134,16 +168,11 @@ export class ForkManager {
|
|
|
134
168
|
return resource;
|
|
135
169
|
}
|
|
136
170
|
|
|
137
|
-
/**
|
|
138
|
-
* Get all resources for an account (with lazy loading)
|
|
139
|
-
*/
|
|
140
171
|
async getAllResources(address: string): Promise<Record<string, any>> {
|
|
141
|
-
const normalizedAddress =
|
|
172
|
+
const normalizedAddress = normalizeAddress(address);
|
|
142
173
|
|
|
143
|
-
// Check if we have any cached resources
|
|
144
174
|
let resources = this.storage.getAllResources(normalizedAddress);
|
|
145
175
|
|
|
146
|
-
// If no cached resources, fetch all from network
|
|
147
176
|
if (Object.keys(resources).length === 0) {
|
|
148
177
|
if (!this.apiClient) {
|
|
149
178
|
throw new Error('Fork not initialized. Call initialize() or load() first.');
|
|
@@ -157,7 +186,6 @@ export class ForkManager {
|
|
|
157
186
|
resources[resource.type] = resource.data;
|
|
158
187
|
}
|
|
159
188
|
|
|
160
|
-
// Cache them
|
|
161
189
|
this.storage.saveAllResources(normalizedAddress, resources);
|
|
162
190
|
console.log(` ✓ Cached ${Object.keys(resources).length} resources`);
|
|
163
191
|
}
|
|
@@ -165,33 +193,32 @@ export class ForkManager {
|
|
|
165
193
|
return resources;
|
|
166
194
|
}
|
|
167
195
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
*/
|
|
171
|
-
async setResource(address: string, resourceType: string, data: any): Promise<void> {
|
|
172
|
-
const normalizedAddress = this.normalizeAddress(address);
|
|
196
|
+
async setResource(address: string, resourceType: string, data: unknown): Promise<void> {
|
|
197
|
+
const normalizedAddress = normalizeAddress(address);
|
|
173
198
|
this.storage.saveResource(normalizedAddress, resourceType, data);
|
|
174
199
|
console.log(` ✓ Updated resource ${resourceType} for ${normalizedAddress}`);
|
|
175
200
|
}
|
|
176
201
|
|
|
177
|
-
/**
|
|
178
|
-
* Fund an account with coins (adds to existing balance)
|
|
179
|
-
*/
|
|
202
|
+
/** Adds to the existing balance rather than replacing it. */
|
|
180
203
|
async fundAccount(address: string, amount: number, coinType: string = '0x1::aptos_coin::AptosCoin'): Promise<void> {
|
|
181
|
-
const normalizedAddress =
|
|
204
|
+
const normalizedAddress = normalizeAddress(address);
|
|
182
205
|
const resourceType = `0x1::coin::CoinStore<${coinType}>`;
|
|
183
206
|
|
|
184
|
-
// Try to get existing coin store
|
|
207
|
+
// Try to get existing coin store. The coin store is a CoinStore<T>
|
|
208
|
+
// resource whose `data` is Movement-side untyped JSON; we shape it
|
|
209
|
+
// locally as a structural object with `coin.value: string`.
|
|
210
|
+
// any: full CoinStore schema lives at the Movement REST boundary —
|
|
211
|
+
// proper validation deferred to the boundary-validation follow-up of #57.
|
|
185
212
|
let coinStore: any;
|
|
186
213
|
try {
|
|
187
214
|
coinStore = await this.getResource(normalizedAddress, resourceType);
|
|
188
|
-
} catch (error
|
|
215
|
+
} catch (error) {
|
|
189
216
|
// Only catch "not found" errors, rethrow others (network, API, etc.)
|
|
190
|
-
|
|
217
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
218
|
+
if (!msg.includes('not found')) {
|
|
191
219
|
throw error;
|
|
192
220
|
}
|
|
193
221
|
|
|
194
|
-
// If doesn't exist, create new one
|
|
195
222
|
coinStore = {
|
|
196
223
|
coin: { value: '0' },
|
|
197
224
|
deposit_events: {
|
|
@@ -216,20 +243,17 @@ export class ForkManager {
|
|
|
216
243
|
};
|
|
217
244
|
}
|
|
218
245
|
|
|
219
|
-
// Add to existing balance (instead of replacing it)
|
|
220
246
|
const currentBalance = BigInt(coinStore.coin.value ?? '0');
|
|
221
247
|
const newBalance = currentBalance + BigInt(amount);
|
|
222
248
|
coinStore.coin.value = newBalance.toString();
|
|
223
249
|
|
|
224
|
-
// Save
|
|
225
250
|
await this.setResource(normalizedAddress, resourceType, coinStore);
|
|
226
251
|
|
|
227
|
-
// Also ensure account exists
|
|
228
252
|
let account = this.storage.getAccount(normalizedAddress);
|
|
229
253
|
if (!account) {
|
|
230
254
|
account = {
|
|
231
255
|
sequenceNumber: '0',
|
|
232
|
-
authenticationKey: normalizedAddress
|
|
256
|
+
authenticationKey: forkAuthKeyPlaceholder(normalizedAddress),
|
|
233
257
|
};
|
|
234
258
|
this.storage.saveAccount(normalizedAddress, account);
|
|
235
259
|
}
|
|
@@ -237,27 +261,6 @@ export class ForkManager {
|
|
|
237
261
|
console.log(` ✓ Funded ${normalizedAddress} with ${amount} coins`);
|
|
238
262
|
}
|
|
239
263
|
|
|
240
|
-
/**
|
|
241
|
-
* Normalize address format
|
|
242
|
-
*/
|
|
243
|
-
private normalizeAddress(address: string): string {
|
|
244
|
-
let normalized = address.toLowerCase();
|
|
245
|
-
|
|
246
|
-
if (!normalized.startsWith('0x')) {
|
|
247
|
-
normalized = `0x${normalized}`;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
// Pad to 66 characters (0x + 64 hex chars)
|
|
251
|
-
if (normalized.length < 66) {
|
|
252
|
-
normalized = '0x' + normalized.slice(2).padStart(64, '0');
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
return normalized;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
/**
|
|
259
|
-
* List all accounts in the fork
|
|
260
|
-
*/
|
|
261
264
|
listAccounts(): string[] {
|
|
262
265
|
return this.storage.listAccounts();
|
|
263
266
|
}
|
|
@@ -267,7 +270,7 @@ export class ForkManager {
|
|
|
267
270
|
*
|
|
268
271
|
* @param addresses Array of addresses to fund
|
|
269
272
|
* @param amount Amount of coins per account
|
|
270
|
-
* @param coinType Coin type (defaults to
|
|
273
|
+
* @param coinType Coin type (defaults to the chain's native coin)
|
|
271
274
|
*
|
|
272
275
|
* @example
|
|
273
276
|
* await forkManager.fundMultipleAccounts(
|
|
@@ -280,13 +283,15 @@ export class ForkManager {
|
|
|
280
283
|
amount: number,
|
|
281
284
|
coinType: string = '0x1::aptos_coin::AptosCoin'
|
|
282
285
|
): Promise<void> {
|
|
283
|
-
|
|
286
|
+
logger.newline();
|
|
287
|
+
logger.step(`Funding ${addresses.length} accounts with ${amount} coins each...`);
|
|
284
288
|
|
|
285
289
|
for (const address of addresses) {
|
|
286
290
|
await this.fundAccount(address, amount, coinType);
|
|
287
291
|
}
|
|
288
292
|
|
|
289
|
-
|
|
293
|
+
logger.success("All accounts funded successfully");
|
|
294
|
+
logger.newline();
|
|
290
295
|
}
|
|
291
296
|
|
|
292
297
|
/**
|
|
@@ -297,13 +302,15 @@ export class ForkManager {
|
|
|
297
302
|
* await forkManager.resetState();
|
|
298
303
|
*/
|
|
299
304
|
async resetState(): Promise<void> {
|
|
300
|
-
|
|
305
|
+
logger.newline();
|
|
306
|
+
logger.step("Resetting fork state...");
|
|
301
307
|
|
|
302
308
|
// Clear all accounts and resources from storage
|
|
303
309
|
this.storage.clearAccounts();
|
|
304
310
|
this.storage.clearResources();
|
|
305
311
|
|
|
306
|
-
|
|
312
|
+
logger.success("Fork state reset to initial snapshot");
|
|
313
|
+
logger.newline();
|
|
307
314
|
}
|
|
308
315
|
|
|
309
316
|
/**
|
|
@@ -317,16 +324,14 @@ export class ForkManager {
|
|
|
317
324
|
* const account = await forkManager.getOrCreateAccount("0x123...");
|
|
318
325
|
*/
|
|
319
326
|
async getOrCreateAccount(address: string): Promise<AccountState> {
|
|
320
|
-
const normalizedAddress =
|
|
327
|
+
const normalizedAddress = normalizeAddress(address);
|
|
321
328
|
|
|
322
|
-
// Try to get existing account
|
|
323
329
|
try {
|
|
324
330
|
return await this.getAccount(normalizedAddress);
|
|
325
331
|
} catch (error) {
|
|
326
|
-
// If account doesn't exist, create a minimal one
|
|
327
332
|
const newAccount: AccountState = {
|
|
328
333
|
sequenceNumber: '0',
|
|
329
|
-
authenticationKey: normalizedAddress
|
|
334
|
+
authenticationKey: forkAuthKeyPlaceholder(normalizedAddress),
|
|
330
335
|
};
|
|
331
336
|
|
|
332
337
|
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
|