gate-evm-tools 1.0.27 → 1.0.31
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 +16 -1
- package/bin/cli.js +3 -0
- package/bin/delivery.cjs +51 -0
- package/bin/manifest-bootstrap.js +4 -15
- package/bin/workflow.cjs +1 -1
- package/dist/commands/plan/file-store.d.ts.map +1 -0
- package/dist/commands/plan/generate-deployment.d.ts +48 -0
- package/dist/commands/plan/generate-deployment.d.ts.map +1 -0
- package/dist/commands/plan/generate-deployment.js +211 -0
- package/dist/commands/plan/generate-deployment.js.map +1 -0
- package/dist/commands/plan/helpers.d.ts.map +1 -0
- package/dist/commands/plan/index.d.ts +3 -0
- package/dist/commands/plan/index.d.ts.map +1 -0
- package/dist/commands/plan/index.js +88 -0
- package/dist/commands/plan/index.js.map +1 -0
- package/dist/commands/sync.js +1 -1
- package/dist/commands/sync.js.map +1 -1
- package/dist/core/BytecodeChecker.d.ts.map +1 -1
- package/dist/core/BytecodeChecker.js +27 -8
- package/dist/core/BytecodeChecker.js.map +1 -1
- package/dist/core/preparation/artifacts.d.ts +2 -0
- package/dist/core/preparation/artifacts.d.ts.map +1 -1
- package/dist/core/preparation/artifacts.js +9 -3
- package/dist/core/preparation/artifacts.js.map +1 -1
- package/dist/core/preparation/evm.d.ts +38 -2
- package/dist/core/preparation/evm.d.ts.map +1 -1
- package/dist/core/preparation/evm.js +104 -32
- package/dist/core/preparation/evm.js.map +1 -1
- package/dist/core/preparation/evmManifestSync.d.ts +63 -0
- package/dist/core/preparation/evmManifestSync.d.ts.map +1 -0
- package/dist/core/preparation/evmManifestSync.js +146 -0
- package/dist/core/preparation/evmManifestSync.js.map +1 -0
- package/dist/core/preparation/index.d.ts +40 -2
- package/dist/core/preparation/index.d.ts.map +1 -1
- package/dist/core/preparation/index.js +3 -3
- package/dist/core/preparation/index.js.map +1 -1
- package/dist/core/preparation/manifest.d.ts +15 -3
- package/dist/core/preparation/manifest.d.ts.map +1 -1
- package/dist/core/preparation/manifest.js +21 -26
- package/dist/core/preparation/manifest.js.map +1 -1
- package/dist/core/preparation/normalize.d.ts.map +1 -1
- package/dist/core/preparation/normalize.js +14 -9
- package/dist/core/preparation/normalize.js.map +1 -1
- package/dist/core/preparation/types.d.ts +7 -2
- package/dist/core/preparation/types.d.ts.map +1 -1
- package/dist/custody/hardhat-runtime.d.ts.map +1 -1
- package/dist/custody/hardhat-runtime.js +2 -0
- package/dist/custody/hardhat-runtime.js.map +1 -1
- package/dist/custody/hardhat.d.ts +1 -0
- package/dist/custody/hardhat.d.ts.map +1 -1
- package/dist/custody/hardhat.js +1 -0
- package/dist/custody/hardhat.js.map +1 -1
- package/dist/custody/index.d.ts +1 -0
- package/dist/custody/index.d.ts.map +1 -1
- package/dist/custody/index.js +1 -0
- package/dist/custody/index.js.map +1 -1
- package/dist/custody/provider-wait.d.ts +13 -0
- package/dist/custody/provider-wait.d.ts.map +1 -0
- package/dist/custody/provider-wait.js +78 -0
- package/dist/custody/provider-wait.js.map +1 -0
- package/dist/delivery/policy.d.ts +6 -0
- package/dist/delivery/policy.d.ts.map +1 -0
- package/dist/delivery/policy.js +24 -0
- package/dist/delivery/policy.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/sync/index.d.ts +15 -0
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +8 -0
- package/dist/sync/index.js.map +1 -1
- package/dist/workflow/index.d.ts +6 -1
- package/dist/workflow/index.d.ts.map +1 -1
- package/dist/workflow/index.js +4 -0
- package/dist/workflow/index.js.map +1 -1
- package/dist-cjs/core/BytecodeChecker.js +526 -0
- package/dist-cjs/core/BytecodeChecker.js.map +1 -0
- package/dist-cjs/core/legacyProxyArtifact.js +42 -0
- package/dist-cjs/core/legacyProxyArtifact.js.map +1 -0
- package/dist-cjs/core/preparation/artifacts.js +11 -4
- package/dist-cjs/core/preparation/artifacts.js.map +1 -1
- package/dist-cjs/core/preparation/evm.js +105 -32
- package/dist-cjs/core/preparation/evm.js.map +1 -1
- package/dist-cjs/core/preparation/evmManifestSync.js +155 -0
- package/dist-cjs/core/preparation/evmManifestSync.js.map +1 -0
- package/dist-cjs/core/preparation/index.js +3 -3
- package/dist-cjs/core/preparation/index.js.map +1 -1
- package/dist-cjs/core/preparation/manifest.js +23 -28
- package/dist-cjs/core/preparation/manifest.js.map +1 -1
- package/dist-cjs/core/preparation/normalize.js +14 -9
- package/dist-cjs/core/preparation/normalize.js.map +1 -1
- package/dist-cjs/custody/hardhat-runtime.js +2 -0
- package/dist-cjs/custody/hardhat-runtime.js.map +1 -1
- package/dist-cjs/custody/hardhat.js +3 -1
- package/dist-cjs/custody/hardhat.js.map +1 -1
- package/dist-cjs/custody/index.js +3 -1
- package/dist-cjs/custody/index.js.map +1 -1
- package/dist-cjs/custody/provider-wait.js +81 -0
- package/dist-cjs/custody/provider-wait.js.map +1 -0
- package/dist-cjs/delivery/policy.js +29 -0
- package/dist-cjs/delivery/policy.js.map +1 -0
- package/dist-cjs/sync/index.js +8 -0
- package/dist-cjs/sync/index.js.map +1 -1
- package/dist-cjs/workflow/index.js +12 -1
- package/dist-cjs/workflow/index.js.map +1 -1
- package/dist-runtime/config/hardhatAdapters.d.ts +2 -0
- package/dist-runtime/config/hardhatAdapters.js +8 -0
- package/dist-runtime/config/hardhatAdapters.js.map +1 -1
- package/dist-runtime/config/networks.d.ts +25 -1
- package/dist-runtime/config/networks.js +8 -2
- package/dist-runtime/config/networks.js.map +1 -1
- package/dist-runtime/config/openzeppelin.d.ts +2 -1
- package/dist-runtime/config/openzeppelin.js +2 -19
- package/dist-runtime/config/openzeppelin.js.map +1 -1
- package/dist-runtime/delivery/abi.d.ts +14 -0
- package/dist-runtime/delivery/abi.js +161 -0
- package/dist-runtime/delivery/abi.js.map +1 -0
- package/dist-runtime/delivery/aggregate-bootstrap.d.ts +12 -0
- package/dist-runtime/delivery/aggregate-bootstrap.js +40 -0
- package/dist-runtime/delivery/aggregate-bootstrap.js.map +1 -0
- package/dist-runtime/delivery/aggregate-channel.d.ts +28 -0
- package/dist-runtime/delivery/aggregate-channel.js +155 -0
- package/dist-runtime/delivery/aggregate-channel.js.map +1 -0
- package/dist-runtime/delivery/aggregate-inputs.d.ts +168 -0
- package/dist-runtime/delivery/aggregate-inputs.js +57 -0
- package/dist-runtime/delivery/aggregate-inputs.js.map +1 -0
- package/dist-runtime/delivery/aggregate-source.d.ts +25 -0
- package/dist-runtime/delivery/aggregate-source.js +79 -0
- package/dist-runtime/delivery/aggregate-source.js.map +1 -0
- package/dist-runtime/delivery/aggregate-worker.d.ts +1 -0
- package/dist-runtime/delivery/aggregate-worker.js +191 -0
- package/dist-runtime/delivery/aggregate-worker.js.map +1 -0
- package/dist-runtime/delivery/aggregate.d.ts +51 -0
- package/dist-runtime/delivery/aggregate.js +190 -0
- package/dist-runtime/delivery/aggregate.js.map +1 -0
- package/dist-runtime/delivery/bindings.d.ts +21 -0
- package/dist-runtime/delivery/bindings.js +53 -0
- package/dist-runtime/delivery/bindings.js.map +1 -0
- package/dist-runtime/delivery/check-code.d.ts +19 -0
- package/dist-runtime/delivery/check-code.js +63 -0
- package/dist-runtime/delivery/check-code.js.map +1 -0
- package/dist-runtime/delivery/closure-format.d.ts +77 -0
- package/dist-runtime/delivery/closure-format.js +225 -0
- package/dist-runtime/delivery/closure-format.js.map +1 -0
- package/dist-runtime/delivery/codec-pin.d.ts +2 -0
- package/dist-runtime/delivery/codec-pin.js +7 -0
- package/dist-runtime/delivery/codec-pin.js.map +1 -0
- package/dist-runtime/delivery/codec.d.ts +19 -0
- package/dist-runtime/delivery/codec.js +73 -0
- package/dist-runtime/delivery/codec.js.map +1 -0
- package/dist-runtime/delivery/compiler-dependency-pins.d.ts +7 -0
- package/dist-runtime/delivery/compiler-dependency-pins.js +1689 -0
- package/dist-runtime/delivery/compiler-dependency-pins.js.map +1 -0
- package/dist-runtime/delivery/compiler-files.d.ts +40 -0
- package/dist-runtime/delivery/compiler-files.js +220 -0
- package/dist-runtime/delivery/compiler-files.js.map +1 -0
- package/dist-runtime/delivery/compiler-io.d.ts +2 -0
- package/dist-runtime/delivery/compiler-io.js +13 -0
- package/dist-runtime/delivery/compiler-io.js.map +1 -0
- package/dist-runtime/delivery/compiler-pins.d.ts +10 -0
- package/dist-runtime/delivery/compiler-pins.js +147 -0
- package/dist-runtime/delivery/compiler-pins.js.map +1 -0
- package/dist-runtime/delivery/compiler.d.ts +188 -0
- package/dist-runtime/delivery/compiler.js +850 -0
- package/dist-runtime/delivery/compiler.js.map +1 -0
- package/dist-runtime/delivery/config.d.ts +48 -0
- package/dist-runtime/delivery/config.js +99 -0
- package/dist-runtime/delivery/config.js.map +1 -0
- package/dist-runtime/delivery/configuration-definition.d.ts +22 -0
- package/dist-runtime/delivery/configuration-definition.js +316 -0
- package/dist-runtime/delivery/configuration-definition.js.map +1 -0
- package/dist-runtime/delivery/configuration-hre.d.ts +17 -0
- package/dist-runtime/delivery/configuration-hre.js +198 -0
- package/dist-runtime/delivery/configuration-hre.js.map +1 -0
- package/dist-runtime/delivery/configuration-runtime.d.ts +36 -0
- package/dist-runtime/delivery/configuration-runtime.js +248 -0
- package/dist-runtime/delivery/configuration-runtime.js.map +1 -0
- package/dist-runtime/delivery/configuration.d.ts +35 -0
- package/dist-runtime/delivery/configuration.js +83 -0
- package/dist-runtime/delivery/configuration.js.map +1 -0
- package/dist-runtime/delivery/create2.d.ts +3 -0
- package/dist-runtime/delivery/create2.js +48 -0
- package/dist-runtime/delivery/create2.js.map +1 -0
- package/dist-runtime/delivery/custom-closure.d.ts +27 -0
- package/dist-runtime/delivery/custom-closure.js +818 -0
- package/dist-runtime/delivery/custom-closure.js.map +1 -0
- package/dist-runtime/delivery/custom-format.d.ts +35 -0
- package/dist-runtime/delivery/custom-format.js +383 -0
- package/dist-runtime/delivery/custom-format.js.map +1 -0
- package/dist-runtime/delivery/custom.d.ts +32 -0
- package/dist-runtime/delivery/custom.js +158 -0
- package/dist-runtime/delivery/custom.js.map +1 -0
- package/dist-runtime/delivery/data.d.ts +7 -0
- package/dist-runtime/delivery/data.js +86 -0
- package/dist-runtime/delivery/data.js.map +1 -0
- package/dist-runtime/delivery/development.d.ts +91 -0
- package/dist-runtime/delivery/development.js +395 -0
- package/dist-runtime/delivery/development.js.map +1 -0
- package/dist-runtime/delivery/engine.d.ts +9 -0
- package/dist-runtime/delivery/engine.js +23 -0
- package/dist-runtime/delivery/engine.js.map +1 -0
- package/dist-runtime/delivery/eoa-observation.d.ts +43 -0
- package/dist-runtime/delivery/eoa-observation.js +145 -0
- package/dist-runtime/delivery/eoa-observation.js.map +1 -0
- package/dist-runtime/delivery/eoa-signed.d.ts +2 -0
- package/dist-runtime/delivery/eoa-signed.js +74 -0
- package/dist-runtime/delivery/eoa-signed.js.map +1 -0
- package/dist-runtime/delivery/eoa.d.ts +81 -0
- package/dist-runtime/delivery/eoa.js +274 -0
- package/dist-runtime/delivery/eoa.js.map +1 -0
- package/dist-runtime/delivery/execution-db.d.ts +20 -0
- package/dist-runtime/delivery/execution-db.js +153 -0
- package/dist-runtime/delivery/execution-db.js.map +1 -0
- package/dist-runtime/delivery/execution-files.d.ts +9 -0
- package/dist-runtime/delivery/execution-files.js +138 -0
- package/dist-runtime/delivery/execution-files.js.map +1 -0
- package/dist-runtime/delivery/execution-model.d.ts +56 -0
- package/dist-runtime/delivery/execution-model.js +66 -0
- package/dist-runtime/delivery/execution-model.js.map +1 -0
- package/dist-runtime/delivery/execution-store.d.ts +48 -0
- package/dist-runtime/delivery/execution-store.js +361 -0
- package/dist-runtime/delivery/execution-store.js.map +1 -0
- package/dist-runtime/delivery/existing-code.d.ts +37 -0
- package/dist-runtime/delivery/existing-code.js +75 -0
- package/dist-runtime/delivery/existing-code.js.map +1 -0
- package/dist-runtime/delivery/export.d.ts +51 -0
- package/dist-runtime/delivery/export.js +69 -0
- package/dist-runtime/delivery/export.js.map +1 -0
- package/dist-runtime/delivery/forkAudit.d.ts +119 -0
- package/dist-runtime/delivery/forkAudit.js +473 -0
- package/dist-runtime/delivery/forkAudit.js.map +1 -0
- package/dist-runtime/delivery/hardhat.d.ts +3 -0
- package/dist-runtime/delivery/hardhat.js +45 -0
- package/dist-runtime/delivery/hardhat.js.map +1 -0
- package/dist-runtime/delivery/history-registration.d.ts +2 -0
- package/dist-runtime/delivery/history-registration.js +17 -0
- package/dist-runtime/delivery/history-registration.js.map +1 -0
- package/dist-runtime/delivery/identities.d.ts +22 -0
- package/dist-runtime/delivery/identities.js +97 -0
- package/dist-runtime/delivery/identities.js.map +1 -0
- package/dist-runtime/delivery/input-files.d.ts +5 -0
- package/dist-runtime/delivery/input-files.js +70 -0
- package/dist-runtime/delivery/input-files.js.map +1 -0
- package/dist-runtime/delivery/inputs.d.ts +62 -0
- package/dist-runtime/delivery/inputs.js +187 -0
- package/dist-runtime/delivery/inputs.js.map +1 -0
- package/dist-runtime/delivery/journal.d.ts +35 -0
- package/dist-runtime/delivery/journal.js +270 -0
- package/dist-runtime/delivery/journal.js.map +1 -0
- package/dist-runtime/delivery/manifest.d.ts +14 -0
- package/dist-runtime/delivery/manifest.js +68 -0
- package/dist-runtime/delivery/manifest.js.map +1 -0
- package/dist-runtime/delivery/materialization.d.ts +20 -0
- package/dist-runtime/delivery/materialization.js +138 -0
- package/dist-runtime/delivery/materialization.js.map +1 -0
- package/dist-runtime/delivery/observations.d.ts +31 -0
- package/dist-runtime/delivery/observations.js +38 -0
- package/dist-runtime/delivery/observations.js.map +1 -0
- package/dist-runtime/delivery/parameters.d.ts +53 -0
- package/dist-runtime/delivery/parameters.js +257 -0
- package/dist-runtime/delivery/parameters.js.map +1 -0
- package/dist-runtime/delivery/pending.d.ts +70 -0
- package/dist-runtime/delivery/pending.js +99 -0
- package/dist-runtime/delivery/pending.js.map +1 -0
- package/dist-runtime/delivery/plan.d.ts +50 -0
- package/dist-runtime/delivery/plan.js +209 -0
- package/dist-runtime/delivery/plan.js.map +1 -0
- package/dist-runtime/delivery/planning.d.ts +81 -0
- package/dist-runtime/delivery/planning.js +302 -0
- package/dist-runtime/delivery/planning.js.map +1 -0
- package/dist-runtime/delivery/policy.d.ts +4 -0
- package/dist-runtime/delivery/policy.js +9 -0
- package/dist-runtime/delivery/policy.js.map +1 -0
- package/dist-runtime/delivery/preparation.d.ts +6 -0
- package/dist-runtime/delivery/preparation.js +158 -0
- package/dist-runtime/delivery/preparation.js.map +1 -0
- package/dist-runtime/delivery/production-environment.d.ts +2 -0
- package/dist-runtime/delivery/production-environment.js +12 -0
- package/dist-runtime/delivery/production-environment.js.map +1 -0
- package/dist-runtime/delivery/production-finalization.d.ts +86 -0
- package/dist-runtime/delivery/production-finalization.js +278 -0
- package/dist-runtime/delivery/production-finalization.js.map +1 -0
- package/dist-runtime/delivery/production.d.ts +461 -0
- package/dist-runtime/delivery/production.js +396 -0
- package/dist-runtime/delivery/production.js.map +1 -0
- package/dist-runtime/delivery/project-files.d.ts +8 -0
- package/dist-runtime/delivery/project-files.js +82 -0
- package/dist-runtime/delivery/project-files.js.map +1 -0
- package/dist-runtime/delivery/project.d.ts +15 -0
- package/dist-runtime/delivery/project.js +157 -0
- package/dist-runtime/delivery/project.js.map +1 -0
- package/dist-runtime/delivery/protocol.d.ts +49 -0
- package/dist-runtime/delivery/protocol.js +112 -0
- package/dist-runtime/delivery/protocol.js.map +1 -0
- package/dist-runtime/delivery/references.d.ts +19 -0
- package/dist-runtime/delivery/references.js +84 -0
- package/dist-runtime/delivery/references.js.map +1 -0
- package/dist-runtime/delivery/release-graph.d.ts +93 -0
- package/dist-runtime/delivery/release-graph.js +106 -0
- package/dist-runtime/delivery/release-graph.js.map +1 -0
- package/dist-runtime/delivery/release-history-capture.d.ts +7 -0
- package/dist-runtime/delivery/release-history-capture.js +76 -0
- package/dist-runtime/delivery/release-history-capture.js.map +1 -0
- package/dist-runtime/delivery/release-history.d.ts +43 -0
- package/dist-runtime/delivery/release-history.js +246 -0
- package/dist-runtime/delivery/release-history.js.map +1 -0
- package/dist-runtime/delivery/release.d.ts +172 -0
- package/dist-runtime/delivery/release.js +209 -0
- package/dist-runtime/delivery/release.js.map +1 -0
- package/dist-runtime/delivery/safe-manifest.d.ts +9 -0
- package/dist-runtime/delivery/safe-manifest.js +13 -0
- package/dist-runtime/delivery/safe-manifest.js.map +1 -0
- package/dist-runtime/delivery/safe-observation.d.ts +30 -0
- package/dist-runtime/delivery/safe-observation.js +487 -0
- package/dist-runtime/delivery/safe-observation.js.map +1 -0
- package/dist-runtime/delivery/safe-prepare.d.ts +13 -0
- package/dist-runtime/delivery/safe-prepare.js +81 -0
- package/dist-runtime/delivery/safe-prepare.js.map +1 -0
- package/dist-runtime/delivery/safe.d.ts +91 -0
- package/dist-runtime/delivery/safe.js +243 -0
- package/dist-runtime/delivery/safe.js.map +1 -0
- package/dist-runtime/delivery/same-fork-baseline.d.ts +8 -0
- package/dist-runtime/delivery/same-fork-baseline.js +20 -0
- package/dist-runtime/delivery/same-fork-baseline.js.map +1 -0
- package/dist-runtime/delivery/setup.d.ts +31 -0
- package/dist-runtime/delivery/setup.js +215 -0
- package/dist-runtime/delivery/setup.js.map +1 -0
- package/dist-runtime/delivery/source.d.ts +41 -0
- package/dist-runtime/delivery/source.js +137 -0
- package/dist-runtime/delivery/source.js.map +1 -0
- package/dist-runtime/delivery/target-fields.d.ts +2 -0
- package/dist-runtime/delivery/target-fields.js +11 -0
- package/dist-runtime/delivery/target-fields.js.map +1 -0
- package/dist-runtime/delivery/validation.d.ts +9 -0
- package/dist-runtime/delivery/validation.js +150 -0
- package/dist-runtime/delivery/validation.js.map +1 -0
- package/dist-runtime/delivery/verification.d.ts +16 -0
- package/dist-runtime/delivery/verification.js +65 -0
- package/dist-runtime/delivery/verification.js.map +1 -0
- package/dist-runtime/migrate.js +1 -0
- package/dist-runtime/migrate.js.map +1 -1
- package/dist-runtime/miner/binary.d.ts +2 -0
- package/dist-runtime/miner/binary.js +54 -0
- package/dist-runtime/miner/binary.js.map +1 -0
- package/dist-runtime/miner/cli.d.ts +1 -0
- package/dist-runtime/miner/cli.js +131 -0
- package/dist-runtime/miner/cli.js.map +1 -0
- package/dist-runtime/miner/index.d.ts +5 -0
- package/dist-runtime/miner/index.js +13 -0
- package/dist-runtime/miner/index.js.map +1 -0
- package/dist-runtime/miner/request.d.ts +7 -0
- package/dist-runtime/miner/request.js +73 -0
- package/dist-runtime/miner/request.js.map +1 -0
- package/dist-runtime/miner/runner.d.ts +2 -0
- package/dist-runtime/miner/runner.js +131 -0
- package/dist-runtime/miner/runner.js.map +1 -0
- package/dist-runtime/miner/types.d.ts +89 -0
- package/dist-runtime/miner/types.js +3 -0
- package/dist-runtime/miner/types.js.map +1 -0
- package/dist-runtime/miner/verify.d.ts +2 -0
- package/dist-runtime/miner/verify.js +75 -0
- package/dist-runtime/miner/verify.js.map +1 -0
- package/dist-runtime/runtime-identity.json +2 -2
- package/dist-runtime/vendor/plan-codec/index.cjs +820 -0
- package/dist-runtime/vendor/plan-codec/index.d.cts +32 -0
- package/dist-runtime/vendor/plan-codec/provenance.json +24 -0
- package/dist-runtime/workflow/engine.d.ts +14 -0
- package/dist-runtime/workflow/engine.js +160 -0
- package/dist-runtime/workflow/engine.js.map +1 -0
- package/dist-runtime/workflow/lib/authority.d.ts +6 -3
- package/dist-runtime/workflow/lib/authority.js.map +1 -1
- package/dist-runtime/workflow/lib/calls.d.ts +1 -1
- package/dist-runtime/workflow/lib/calls.js +43 -34
- package/dist-runtime/workflow/lib/calls.js.map +1 -1
- package/dist-runtime/workflow/lib/canonicalData.d.ts +8 -0
- package/dist-runtime/workflow/lib/canonicalData.js +68 -0
- package/dist-runtime/workflow/lib/canonicalData.js.map +1 -0
- package/dist-runtime/workflow/lib/config.d.ts +3 -1
- package/dist-runtime/workflow/lib/config.js.map +1 -1
- package/dist-runtime/workflow/lib/context.d.ts +76 -0
- package/dist-runtime/workflow/lib/context.js +3 -0
- package/dist-runtime/workflow/lib/context.js.map +1 -0
- package/dist-runtime/workflow/lib/controlledMulticallAbi.d.ts +2 -0
- package/dist-runtime/workflow/lib/controlledMulticallAbi.js +10 -0
- package/dist-runtime/workflow/lib/controlledMulticallAbi.js.map +1 -0
- package/dist-runtime/workflow/lib/create2.d.ts +1 -1
- package/dist-runtime/workflow/lib/create2.js +9 -12
- package/dist-runtime/workflow/lib/create2.js.map +1 -1
- package/dist-runtime/workflow/lib/deployments.d.ts +5 -5
- package/dist-runtime/workflow/lib/deployments.js +5 -13
- package/dist-runtime/workflow/lib/deployments.js.map +1 -1
- package/dist-runtime/workflow/lib/evidencePorts.d.ts +55 -0
- package/dist-runtime/workflow/lib/evidencePorts.js +3 -0
- package/dist-runtime/workflow/lib/evidencePorts.js.map +1 -0
- package/dist-runtime/workflow/lib/executionPlan.d.ts +4 -42
- package/dist-runtime/workflow/lib/executionPlan.js +15 -210
- package/dist-runtime/workflow/lib/executionPlan.js.map +1 -1
- package/dist-runtime/workflow/lib/gateTool.d.ts +6 -2
- package/dist-runtime/workflow/lib/gateTool.js +20 -10
- package/dist-runtime/workflow/lib/gateTool.js.map +1 -1
- package/dist-runtime/workflow/lib/gateToolSync.d.ts +1 -1
- package/dist-runtime/workflow/lib/gateToolSync.js +3 -2
- package/dist-runtime/workflow/lib/gateToolSync.js.map +1 -1
- package/dist-runtime/workflow/lib/operationNames.d.ts +3 -0
- package/dist-runtime/workflow/lib/operationNames.js +34 -0
- package/dist-runtime/workflow/lib/operationNames.js.map +1 -0
- package/dist-runtime/workflow/lib/parameters.d.ts +1 -1
- package/dist-runtime/workflow/lib/parameters.js +9 -24
- package/dist-runtime/workflow/lib/parameters.js.map +1 -1
- package/dist-runtime/workflow/lib/pendingDeploymentReuse.js +18 -52
- package/dist-runtime/workflow/lib/pendingDeploymentReuse.js.map +1 -1
- package/dist-runtime/workflow/lib/pendingUupsBinding.d.ts +42 -0
- package/dist-runtime/workflow/lib/pendingUupsBinding.js +39 -0
- package/dist-runtime/workflow/lib/pendingUupsBinding.js.map +1 -0
- package/dist-runtime/workflow/lib/plan.d.ts +55 -0
- package/dist-runtime/workflow/lib/plan.js +324 -0
- package/dist-runtime/workflow/lib/plan.js.map +1 -0
- package/dist-runtime/workflow/lib/planCli.d.ts +14 -0
- package/dist-runtime/workflow/lib/planCli.js +279 -0
- package/dist-runtime/workflow/lib/planCli.js.map +1 -0
- package/dist-runtime/workflow/lib/preparationEvidence.d.ts +4 -0
- package/dist-runtime/workflow/lib/preparationEvidence.js +19 -0
- package/dist-runtime/workflow/lib/preparationEvidence.js.map +1 -0
- package/dist-runtime/workflow/lib/proxy.d.ts +3 -2
- package/dist-runtime/workflow/lib/proxy.js +3 -4
- package/dist-runtime/workflow/lib/proxy.js.map +1 -1
- package/dist-runtime/workflow/lib/runtime.d.ts +6 -0
- package/dist-runtime/workflow/lib/runtime.js +48 -0
- package/dist-runtime/workflow/lib/runtime.js.map +1 -0
- package/dist-runtime/workflow/lib/signer.d.ts +3 -2
- package/dist-runtime/workflow/lib/signer.js +18 -18
- package/dist-runtime/workflow/lib/signer.js.map +1 -1
- package/dist-runtime/workflow/lib/simulation.d.ts +13 -6
- package/dist-runtime/workflow/lib/simulation.js +39 -31
- package/dist-runtime/workflow/lib/simulation.js.map +1 -1
- package/dist-runtime/workflow/lib/state.js +3 -3
- package/dist-runtime/workflow/lib/state.js.map +1 -1
- package/dist-runtime/workflow/lib/staticValidation.d.ts +28 -0
- package/dist-runtime/workflow/lib/staticValidation.js +54 -10
- package/dist-runtime/workflow/lib/staticValidation.js.map +1 -1
- package/dist-runtime/workflow/lib/transactionPlanner.d.ts +62 -0
- package/dist-runtime/workflow/lib/transactionPlanner.js +258 -0
- package/dist-runtime/workflow/lib/transactionPlanner.js.map +1 -0
- package/dist-runtime/workflow/lib/typedValue.d.ts +3 -0
- package/dist-runtime/workflow/lib/typedValue.js +76 -0
- package/dist-runtime/workflow/lib/typedValue.js.map +1 -0
- package/dist-runtime/workflow/lib/validation.d.ts +23 -0
- package/dist-runtime/workflow/lib/validation.js +15 -0
- package/dist-runtime/workflow/lib/validation.js.map +1 -0
- package/dist-runtime/workflow/planAdd.d.ts +1 -0
- package/dist-runtime/workflow/planAdd.js +11 -0
- package/dist-runtime/workflow/planAdd.js.map +1 -0
- package/dist-runtime/workflow/planRead.d.ts +1 -0
- package/dist-runtime/workflow/planRead.js +11 -0
- package/dist-runtime/workflow/planRead.js.map +1 -0
- package/dist-runtime/workflow/planStatus.d.ts +1 -0
- package/dist-runtime/workflow/planStatus.js +11 -0
- package/dist-runtime/workflow/planStatus.js.map +1 -0
- package/dist-runtime/workflow/planWrite.d.ts +1 -0
- package/dist-runtime/workflow/planWrite.js +11 -0
- package/dist-runtime/workflow/planWrite.js.map +1 -0
- package/dist-runtime/workflow/run.d.ts +1 -40
- package/dist-runtime/workflow/run.js +68 -136
- package/dist-runtime/workflow/run.js.map +1 -1
- package/dist-runtime/workflow/staticValidate.js +8 -3
- package/dist-runtime/workflow/staticValidate.js.map +1 -1
- package/dist-runtime/workflow/steps/call.d.ts +1 -1
- package/dist-runtime/workflow/steps/check.d.ts +1 -1
- package/dist-runtime/workflow/steps/custom.d.ts +1 -1
- package/dist-runtime/workflow/steps/deploy.d.ts +1 -1
- package/dist-runtime/workflow/steps/deploy.js +58 -55
- package/dist-runtime/workflow/steps/deploy.js.map +1 -1
- package/dist-runtime/workflow/steps/upgrade.d.ts +1 -1
- package/dist-runtime/workflow/steps/upgrade.js +63 -41
- package/dist-runtime/workflow/steps/upgrade.js.map +1 -1
- package/dist-runtime/workflow/steps/view.d.ts +1 -1
- package/docs/compiler-qualification.md +32 -0
- package/docs/configuration-runtime-observation.md +29 -0
- package/docs/create2-miner.md +100 -0
- package/docs/delivery-aggregate.md +27 -0
- package/docs/delivery-custom-input-closure.md +51 -0
- package/docs/delivery-development.md +32 -0
- package/docs/delivery-eoa.md +46 -0
- package/docs/delivery-evm-manifest.md +20 -0
- package/docs/delivery-execution-store.md +33 -0
- package/docs/delivery-inputs.md +46 -0
- package/docs/delivery-parameters.md +65 -0
- package/docs/delivery-planning.md +140 -0
- package/docs/delivery-release.md +65 -0
- package/docs/delivery-safe.md +72 -0
- package/docs/delivery-setup.md +146 -0
- package/docs/delivery-source.md +67 -0
- package/docs/direct-package-acceptance.md +20 -0
- package/docs/external-infrastructure-acceptance.md +33 -0
- package/docs/network-runtime-acceptance.md +18 -0
- package/docs/plans/2026-09-09-workflow-extraction.md +16 -0
- package/docs/superpowers/plans/2026-07-22-manifest-bootstrap-transaction.md +50 -0
- package/docs/superpowers/plans/2026-07-22-manifest-review-remediation.md +49 -0
- package/docs/superpowers/plans/2026-08-17-custody-hardhat-signers.md +227 -0
- package/docs/superpowers/plans/2026-09-09-remove-template-infrastructure-contracts.md +11 -0
- package/docs/superpowers/plans/2026-09-24-scheme-aware-static-validation.md +193 -0
- package/docs/superpowers/plans/2026-10-28-create2-miner.md +82 -0
- package/docs/workflow-reference.md +1181 -0
- package/docs/workflow-runtime-acceptance.md +17 -0
- package/docs/workflow-runtime.md +56 -0
- package/package.json +134 -9
- package/resources/create2/LICENSE +21 -0
- package/resources/create2/README.md +9 -0
- package/resources/create2/darwin-arm64/smartflow_miner +0 -0
- package/resources/create2/darwin-x64/smartflow_miner +0 -0
- package/resources/create2/manifest.json +27 -0
- package/runtime/config/hardhatAdapters.ts +8 -0
- package/runtime/config/networks.ts +20 -11
- package/runtime/config/openzeppelin.ts +3 -21
- package/runtime/delivery/abi.ts +225 -0
- package/runtime/delivery/aggregate-bootstrap.ts +29 -0
- package/runtime/delivery/aggregate-channel.ts +85 -0
- package/runtime/delivery/aggregate-inputs.ts +39 -0
- package/runtime/delivery/aggregate-source.ts +53 -0
- package/runtime/delivery/aggregate-worker.ts +133 -0
- package/runtime/delivery/aggregate.ts +139 -0
- package/runtime/delivery/bindings.ts +37 -0
- package/runtime/delivery/check-code.ts +38 -0
- package/runtime/delivery/closure-format.ts +350 -0
- package/runtime/delivery/codec-pin.ts +3 -0
- package/runtime/delivery/codec.ts +50 -0
- package/runtime/delivery/compiler-dependency-pins.ts +1685 -0
- package/runtime/delivery/compiler-files.ts +179 -0
- package/runtime/delivery/compiler-io.ts +10 -0
- package/runtime/delivery/compiler-pins.ts +143 -0
- package/runtime/delivery/compiler.ts +700 -0
- package/runtime/delivery/config.ts +93 -0
- package/runtime/delivery/configuration-definition.ts +133 -0
- package/runtime/delivery/configuration-hre.ts +130 -0
- package/runtime/delivery/configuration-runtime.ts +163 -0
- package/runtime/delivery/configuration.ts +64 -0
- package/runtime/delivery/create2.ts +57 -0
- package/runtime/delivery/custom-closure.ts +993 -0
- package/runtime/delivery/custom-format.ts +464 -0
- package/runtime/delivery/custom.ts +219 -0
- package/runtime/delivery/data.ts +94 -0
- package/runtime/delivery/development.ts +262 -0
- package/runtime/delivery/engine.ts +29 -0
- package/runtime/delivery/eoa-observation.ts +106 -0
- package/runtime/delivery/eoa-signed.ts +55 -0
- package/runtime/delivery/eoa.ts +288 -0
- package/runtime/delivery/execution-db.ts +131 -0
- package/runtime/delivery/execution-files.ts +135 -0
- package/runtime/delivery/execution-model.ts +102 -0
- package/runtime/delivery/execution-store.ts +411 -0
- package/runtime/delivery/existing-code.ts +44 -0
- package/runtime/delivery/export.ts +99 -0
- package/runtime/delivery/forkAudit.ts +620 -0
- package/runtime/delivery/hardhat.ts +38 -0
- package/runtime/delivery/history-registration.ts +10 -0
- package/runtime/delivery/identities.ts +132 -0
- package/runtime/delivery/input-files.ts +46 -0
- package/runtime/delivery/inputs.ts +197 -0
- package/runtime/delivery/journal.ts +201 -0
- package/runtime/delivery/manifest.ts +54 -0
- package/runtime/delivery/materialization.ts +53 -0
- package/runtime/delivery/observations.ts +60 -0
- package/runtime/delivery/parameters.ts +349 -0
- package/runtime/delivery/pending.ts +98 -0
- package/runtime/delivery/plan.ts +337 -0
- package/runtime/delivery/planning.ts +397 -0
- package/runtime/delivery/policy.ts +9 -0
- package/runtime/delivery/preparation.ts +224 -0
- package/runtime/delivery/production-environment.ts +6 -0
- package/runtime/delivery/production-finalization.ts +172 -0
- package/runtime/delivery/production.ts +375 -0
- package/runtime/delivery/project-files.ts +58 -0
- package/runtime/delivery/project.ts +117 -0
- package/runtime/delivery/protocol.ts +94 -0
- package/runtime/delivery/references.ts +106 -0
- package/runtime/delivery/release-graph.ts +49 -0
- package/runtime/delivery/release-history-capture.ts +32 -0
- package/runtime/delivery/release-history.ts +120 -0
- package/runtime/delivery/release.ts +128 -0
- package/runtime/delivery/safe-manifest.ts +11 -0
- package/runtime/delivery/safe-observation.ts +626 -0
- package/runtime/delivery/safe-prepare.ts +101 -0
- package/runtime/delivery/safe.ts +344 -0
- package/runtime/delivery/same-fork-baseline.ts +16 -0
- package/runtime/delivery/setup.ts +172 -0
- package/runtime/delivery/source.ts +130 -0
- package/runtime/delivery/target-fields.ts +7 -0
- package/runtime/delivery/validation.ts +247 -0
- package/runtime/delivery/verification.ts +47 -0
- package/runtime/migrate.ts +1 -0
- package/runtime/miner/binary.ts +41 -0
- package/runtime/miner/cli.ts +87 -0
- package/runtime/miner/index.ts +5 -0
- package/runtime/miner/request.ts +54 -0
- package/runtime/miner/runner.ts +90 -0
- package/runtime/miner/types.ts +71 -0
- package/runtime/miner/verify.ts +61 -0
- package/runtime/vendor/plan-codec/index.cjs +820 -0
- package/runtime/vendor/plan-codec/index.d.cts +32 -0
- package/runtime/vendor/plan-codec/provenance.json +24 -0
- package/runtime/workflow/engine.ts +174 -0
- package/runtime/workflow/lib/authority.ts +3 -3
- package/runtime/workflow/lib/calls.ts +46 -37
- package/runtime/workflow/lib/canonicalData.ts +45 -0
- package/runtime/workflow/lib/config.ts +1 -1
- package/runtime/workflow/lib/context.ts +76 -0
- package/runtime/workflow/lib/controlledMulticallAbi.ts +6 -0
- package/runtime/workflow/lib/create2.ts +10 -12
- package/runtime/workflow/lib/deployments.ts +6 -14
- package/runtime/workflow/lib/evidencePorts.ts +20 -0
- package/runtime/workflow/lib/executionPlan.ts +17 -268
- package/runtime/workflow/lib/gateTool.ts +20 -8
- package/runtime/workflow/lib/gateToolSync.ts +3 -3
- package/runtime/workflow/lib/operationNames.ts +32 -0
- package/runtime/workflow/lib/parameters.ts +7 -23
- package/runtime/workflow/lib/pendingDeploymentReuse.ts +4 -56
- package/runtime/workflow/lib/pendingUupsBinding.ts +43 -0
- package/runtime/workflow/lib/plan.ts +334 -0
- package/runtime/workflow/lib/planCli.ts +279 -0
- package/runtime/workflow/lib/preparationEvidence.ts +14 -0
- package/runtime/workflow/lib/proxy.ts +5 -3
- package/runtime/workflow/lib/runtime.ts +46 -0
- package/runtime/workflow/lib/signer.ts +8 -5
- package/runtime/workflow/lib/simulation.ts +41 -17
- package/runtime/workflow/lib/state.ts +3 -3
- package/runtime/workflow/lib/staticValidation.ts +92 -11
- package/runtime/workflow/lib/transactionPlanner.ts +314 -0
- package/runtime/workflow/lib/typedValue.ts +46 -0
- package/runtime/workflow/lib/validation.ts +50 -0
- package/runtime/workflow/planAdd.ts +8 -0
- package/runtime/workflow/planRead.ts +8 -0
- package/runtime/workflow/planStatus.ts +8 -0
- package/runtime/workflow/planWrite.ts +8 -0
- package/runtime/workflow/run.ts +41 -174
- package/runtime/workflow/staticValidate.ts +8 -3
- package/runtime/workflow/steps/call.ts +1 -1
- package/runtime/workflow/steps/check.ts +1 -1
- package/runtime/workflow/steps/custom.ts +1 -1
- package/runtime/workflow/steps/deploy.ts +59 -59
- package/runtime/workflow/steps/upgrade.ts +71 -47
- package/runtime/workflow/steps/view.ts +1 -1
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
/** Host-injected EOA execution kernel. It is not a production host or Safe adapter. */
|
|
2
|
+
import { observeSafeTransaction } from './safe-observation';
|
|
3
|
+
import { prepareSafeEnvelope, parseSafeTarget } from './safe-prepare';
|
|
4
|
+
import { renderSafeExport } from './safe';
|
|
5
|
+
import { deepFreeze, semanticHash } from '../workflow/lib/canonicalData';
|
|
6
|
+
import { immutableDeliveryPlan, renderDeliveryExport, validateDeliveryProgress } from './export';
|
|
7
|
+
import { parseUnsigned, same, type ExecutionSnapshot, type UnsignedEnvelope, type TransactionRecord } from './execution-model';
|
|
8
|
+
import type { ExecutionClaim, ExecutionStore } from './execution-store';
|
|
9
|
+
import { hash32, type TransactionObservation } from './observations';
|
|
10
|
+
import { EoaRpcFailure, executionContext, observeEoaTransaction, verifyEoaChain, verifyEoaCode, type EoaExecutionContext, type EoaRpc } from './eoa-observation';
|
|
11
|
+
import { verifyEoaSigned } from './eoa-signed';
|
|
12
|
+
export { verifyEoaSigned } from './eoa-signed';
|
|
13
|
+
export { observeEoaTransaction, eoaObservationReference } from './eoa-observation';
|
|
14
|
+
export type { EoaRpc, EoaExecutionContext, EoaFinality, EoaObservationRequest } from './eoa-observation';
|
|
15
|
+
export interface EoaApprovalSnapshot {
|
|
16
|
+
context: EoaExecutionContext;
|
|
17
|
+
transaction: ExecutionSnapshot['plan']['transactions'][number];
|
|
18
|
+
unsigned: UnsignedEnvelope;
|
|
19
|
+
signingRequestId: string;
|
|
20
|
+
}
|
|
21
|
+
/** Supplied only by controlled trusted host code. JSON flags and agent-provided functions confer no authority. */
|
|
22
|
+
export interface EoaApprovalCapability {
|
|
23
|
+
withApproval<T>(snapshot: EoaApprovalSnapshot, controlledWork: () => Promise<T>): Promise<T>;
|
|
24
|
+
}
|
|
25
|
+
export interface EoaSignOnlySigner {
|
|
26
|
+
address: string;
|
|
27
|
+
/** Must sign only, retain the result under this immutable request ID, and NEVER broadcast. */
|
|
28
|
+
sign(signingRequestId: string, unsigned: UnsignedEnvelope): Promise<string>;
|
|
29
|
+
/** Read-only original-result lookup. Never start new signing when the intent is uncertain. */
|
|
30
|
+
recover?(signingRequestId: string): Promise<string | undefined>;
|
|
31
|
+
}
|
|
32
|
+
export interface EoaExecutionOptions {
|
|
33
|
+
plan: unknown;
|
|
34
|
+
context: EoaExecutionContext;
|
|
35
|
+
store: ExecutionStore;
|
|
36
|
+
provider: EoaRpc;
|
|
37
|
+
signer?: EoaSignOnlySigner;
|
|
38
|
+
approval?: EoaApprovalCapability;
|
|
39
|
+
}
|
|
40
|
+
export interface EoaExecutionResult {
|
|
41
|
+
status: 'submitted' | 'pending' | 'advanced' | 'complete' | 'reverted' | 'signing-result-unavailable';
|
|
42
|
+
snapshot: ExecutionSnapshot;
|
|
43
|
+
}
|
|
44
|
+
/** Explicit finite hash sets by plan transaction ID. No discovery, scanning, or implicit resend. */
|
|
45
|
+
export type EoaHashReferences = Readonly<Record<string, readonly string[]>>;
|
|
46
|
+
export function createDeliveryEoaExecution(options: EoaExecutionOptions) {
|
|
47
|
+
const plan = immutableDeliveryPlan(options.plan), context = executionContext(options.context, plan);
|
|
48
|
+
const contextHash = semanticHash({ schema: 'gate-delivery-eoa-context', version: 1, context });
|
|
49
|
+
const { store, provider, signer, approval } = options;
|
|
50
|
+
async function claim<T>(work: (claim: ExecutionClaim, snapshot: ExecutionSnapshot) => Promise<T>): Promise<T> {
|
|
51
|
+
const previous = await store.readExecution(plan.executionId);
|
|
52
|
+
return store.withExecutionClaim({ plan, contextHash, expectedRevision: previous?.revision ?? null }, async (c, s) => {
|
|
53
|
+
if (s.blockedReason !== null)
|
|
54
|
+
throw new Error(`Execution blocked: ${s.blockedReason}`);
|
|
55
|
+
await verifyPrefix(c, s);
|
|
56
|
+
return work(c, s);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
function read(tx: TransactionRecord, transactionHash: string): Promise<TransactionObservation | undefined> {
|
|
60
|
+
return observeEoaTransaction({ plan, context, provider, index: tx.index, transactionHash, original: tx.signed && tx.unsigned ? { unsigned: tx.unsigned, signed: tx.signed } : undefined });
|
|
61
|
+
}
|
|
62
|
+
async function verifyPrefix(c: ExecutionClaim, s: ExecutionSnapshot): Promise<TransactionObservation[]> {
|
|
63
|
+
const completed: TransactionObservation[] = [], hashes = new Set<string>(), batches = new Map<string, TransactionObservation[]>();
|
|
64
|
+
for (const tx of s.transactions.slice(0, s.completedCount)) {
|
|
65
|
+
// Transport errors stop this invocation. A successful query showing lost evidence is durable finality loss.
|
|
66
|
+
let current: TransactionObservation | undefined;
|
|
67
|
+
try {
|
|
68
|
+
if (tx.observation?.safe) {
|
|
69
|
+
const id = tx.observation.safe.envelopeId, e = s.safeEnvelopes.find(e => e.envelopeId === id);
|
|
70
|
+
if (!e)
|
|
71
|
+
throw Error('Missing frozen Safe prefix');
|
|
72
|
+
let rows = batches.get(id);
|
|
73
|
+
if (!rows) {
|
|
74
|
+
rows = await observeSafeTransaction({ plan, envelope: e, provider, transactionHash: tx.observation.transactionHash });
|
|
75
|
+
if (rows)
|
|
76
|
+
batches.set(id, rows);
|
|
77
|
+
}
|
|
78
|
+
current = rows?.[tx.observation.safe.innerCallIndex];
|
|
79
|
+
}
|
|
80
|
+
else
|
|
81
|
+
current = await read(tx, tx.observation!.transactionHash);
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
if (error instanceof EoaRpcFailure)
|
|
85
|
+
throw error;
|
|
86
|
+
store.blockExecution(c, s.revision, 'Previously finalized execution identity no longer verifies');
|
|
87
|
+
throw new Error('Previously finalized execution identity no longer verifies; execution blocked', { cause: error });
|
|
88
|
+
}
|
|
89
|
+
if (!current || current.state !== 'finalized-success' || !same(current, tx.observation) || (hashes.has(current.transactionHash) && (!current.safe || current.safe.innerCallIndex === 0))) {
|
|
90
|
+
store.blockExecution(c, s.revision, 'Previously finalized execution progress lost canonical finality');
|
|
91
|
+
throw new Error('Previously finalized execution progress lost canonical finality; execution blocked');
|
|
92
|
+
}
|
|
93
|
+
hashes.add(current.transactionHash);
|
|
94
|
+
completed.push(current);
|
|
95
|
+
}
|
|
96
|
+
return completed;
|
|
97
|
+
}
|
|
98
|
+
async function reconcileActive(c: ExecutionClaim, s: ExecutionSnapshot, references: EoaHashReferences): Promise<EoaExecutionResult> {
|
|
99
|
+
const start = s.completedCount;
|
|
100
|
+
while (s.completedCount < s.transactions.length) {
|
|
101
|
+
const tx = s.transactions[s.completedCount];
|
|
102
|
+
if (tx.state === 'finalized-reverted')
|
|
103
|
+
return { status: 'reverted', snapshot: s };
|
|
104
|
+
if (tx.state === 'blocked')
|
|
105
|
+
throw new Error('Transaction blocked');
|
|
106
|
+
const safe = s.safeEnvelopes.find(e => e.start === tx.index);
|
|
107
|
+
if (safe) {
|
|
108
|
+
const supplied = safe.transactionIds.flatMap(id => references[id] ?? []), candidates = [...new Set(supplied)];
|
|
109
|
+
if (candidates.length > 1)
|
|
110
|
+
throw Error('Supply one original outer Safe hash per envelope');
|
|
111
|
+
if (!candidates.length)
|
|
112
|
+
break;
|
|
113
|
+
const hash = hash32(candidates[0], 'Safe original hash');
|
|
114
|
+
if (s.transactions.some(t => t.observation?.transactionHash === hash))
|
|
115
|
+
throw Error('Safe hash already consumed');
|
|
116
|
+
const rows = await observeSafeTransaction({ plan, envelope: safe, provider, transactionHash: hash });
|
|
117
|
+
if (!rows)
|
|
118
|
+
break;
|
|
119
|
+
if (rows[0].state === 'finalized-reverted')
|
|
120
|
+
return { status: 'reverted', snapshot: s };
|
|
121
|
+
if (rows[0].state !== 'finalized-success')
|
|
122
|
+
break;
|
|
123
|
+
s = await store.recordSafeObservations(c, s.revision, safe.envelopeId, { readSafeObservations: async () => rows });
|
|
124
|
+
await verifyPrefix(c, s);
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
const supplied = references[tx.transactionId] ?? [];
|
|
128
|
+
if (!Array.isArray(supplied))
|
|
129
|
+
throw new Error('Expected explicit transaction hash set');
|
|
130
|
+
const candidates = tx.signed ? [tx.signed.transactionHash] : [...new Set([...supplied, ...(tx.observation ? [tx.observation.transactionHash] : [])])];
|
|
131
|
+
if (tx.signed && supplied.some(h => h !== tx.signed!.transactionHash))
|
|
132
|
+
throw new Error('Hash reference differs from original signed identity');
|
|
133
|
+
// Signing intent without durable bytes may only recover the original signature first.
|
|
134
|
+
if (tx.state === 'signing')
|
|
135
|
+
return { status: 'signing-result-unavailable', snapshot: s };
|
|
136
|
+
let selected: TransactionObservation | undefined;
|
|
137
|
+
for (const hash of candidates) {
|
|
138
|
+
hash32(hash, 'explicit transaction hash');
|
|
139
|
+
if (s.transactions.slice(0, s.completedCount).some(t => t.observation?.transactionHash === hash))
|
|
140
|
+
throw new Error('Duplicate hash already completed a plan entry');
|
|
141
|
+
const observation = await read(tx, hash);
|
|
142
|
+
if (!observation)
|
|
143
|
+
continue;
|
|
144
|
+
if (selected && selected.transactionHash !== observation.transactionHash)
|
|
145
|
+
throw new Error('Ambiguous matching transaction hash set; supply one reference');
|
|
146
|
+
selected = observation;
|
|
147
|
+
}
|
|
148
|
+
if (!selected)
|
|
149
|
+
break;
|
|
150
|
+
const observed = selected;
|
|
151
|
+
s = await store.recordObservation(c, s.revision, observed.observationId, { readObservation: async () => observed });
|
|
152
|
+
if (observed.state === 'finalized-reverted')
|
|
153
|
+
return { status: 'reverted', snapshot: s };
|
|
154
|
+
if (observed.state !== 'finalized-success')
|
|
155
|
+
break;
|
|
156
|
+
// Recheck the entire accepted prefix before a subsequent advancement.
|
|
157
|
+
await verifyPrefix(c, s);
|
|
158
|
+
}
|
|
159
|
+
return { status: s.completedCount === s.transactions.length ? 'complete' : s.completedCount > start ? 'advanced' : 'pending', snapshot: s };
|
|
160
|
+
}
|
|
161
|
+
async function approved<T>(snapshot: EoaApprovalSnapshot, work: (assertApproval: () => void) => Promise<T>): Promise<T> {
|
|
162
|
+
if (typeof approval?.withApproval !== 'function')
|
|
163
|
+
throw new Error('Trusted host approval capability unavailable');
|
|
164
|
+
let started = false, accepting = true, pending: Promise<T> | undefined;
|
|
165
|
+
try {
|
|
166
|
+
await approval.withApproval(snapshot, () => {
|
|
167
|
+
if (!accepting || started)
|
|
168
|
+
throw new Error('Approval work is revoked or already consumed');
|
|
169
|
+
started = true;
|
|
170
|
+
pending = work(() => { if (!accepting)
|
|
171
|
+
throw new Error('Host approval scope revoked'); });
|
|
172
|
+
return pending;
|
|
173
|
+
});
|
|
174
|
+
accepting = false;
|
|
175
|
+
if (!pending)
|
|
176
|
+
throw new Error('Host approval did not authorize controlled work');
|
|
177
|
+
return await pending;
|
|
178
|
+
}
|
|
179
|
+
finally {
|
|
180
|
+
accepting = false;
|
|
181
|
+
if (pending)
|
|
182
|
+
await pending.catch(() => undefined);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return Object.freeze({
|
|
186
|
+
/** Current segment only; an existing frozen payload is returned without nonce rebasing. */
|
|
187
|
+
async prepareSafe(rawProfile: unknown) { const profile = parseSafeTarget(rawProfile); return claim(async (c, s) => { const prior = s.safeEnvelopes.find(e => e.start === s.completedCount); if (prior) {
|
|
188
|
+
if (prior.adapter !== profile.adapter || prior.multiSend !== profile.multiSendCallOnly || prior.safeTxGas !== profile.safeTxGas || !same(prior.submitter, profile.submitterPolicy) || !same(prior.finality, context.finality))
|
|
189
|
+
throw Error('Frozen Safe policy conflict');
|
|
190
|
+
const live = await prepareSafeEnvelope(plan, s.completedCount, profile, provider, context.finality);
|
|
191
|
+
if (live.nonce !== prior.nonce)
|
|
192
|
+
throw Error('Frozen Safe nonce consumed; reconcile the original hash without rebasing');
|
|
193
|
+
if (!same(live, prior))
|
|
194
|
+
throw Error('Frozen Safe execution identity changed');
|
|
195
|
+
return { envelope: prior, snapshot: s };
|
|
196
|
+
} const envelope = await prepareSafeEnvelope(plan, s.completedCount, profile, provider, context.finality); s = store.freezeSafeEnvelope(c, s.revision, envelope); return { envelope, snapshot: s }; }); },
|
|
197
|
+
/** One active operator transaction per call. Frozen envelopes are explicit; no implicit gas/nonce defaults. */
|
|
198
|
+
async execute(rawUnsigned?: unknown): Promise<EoaExecutionResult> {
|
|
199
|
+
return claim(async (c, initial) => {
|
|
200
|
+
let s = initial, tx = s.transactions[s.completedCount];
|
|
201
|
+
if (!tx)
|
|
202
|
+
return { status: 'complete', snapshot: s };
|
|
203
|
+
if (tx.state === 'finalized-reverted' || tx.state === 'blocked')
|
|
204
|
+
throw new Error('Reverted or blocked transaction');
|
|
205
|
+
if (['submission-uncertain', 'included-unfinalized'].includes(tx.state))
|
|
206
|
+
return reconcileActive(c, s, {});
|
|
207
|
+
const planned = plan.transactions[tx.index];
|
|
208
|
+
if (planned.operation !== 0)
|
|
209
|
+
throw new Error('Unsupported EOA operation');
|
|
210
|
+
if (planned.route !== 'operator' || planned.executor !== context.operator)
|
|
211
|
+
throw new Error('Only active operator-route executor may sign');
|
|
212
|
+
if (!signer || typeof signer.sign !== 'function' || signer.address !== context.operator)
|
|
213
|
+
throw new Error('Approved EOA signer unavailable or mismatched');
|
|
214
|
+
if (typeof approval?.withApproval !== 'function')
|
|
215
|
+
throw new Error('Trusted host approval capability unavailable');
|
|
216
|
+
await verifyEoaChain(provider, context);
|
|
217
|
+
await verifyEoaCode(provider, planned.executor, 'latest');
|
|
218
|
+
const unsigned = rawUnsigned === undefined ? tx.unsigned : parseUnsigned(rawUnsigned, plan, tx.index);
|
|
219
|
+
if (!unsigned)
|
|
220
|
+
throw new Error('Complete explicit unsigned approval snapshot required');
|
|
221
|
+
if (tx.unsigned && !same(unsigned, tx.unsigned))
|
|
222
|
+
throw new Error('Frozen approval snapshot mismatch');
|
|
223
|
+
s = store.freezeAndReserve(c, s.revision, tx.transactionId, unsigned);
|
|
224
|
+
tx = s.transactions[s.completedCount];
|
|
225
|
+
const signingRequestId = semanticHash({ schema: 'gate-delivery-eoa-signing-request', version: 1, context, transaction: planned, unsigned });
|
|
226
|
+
if (tx.signingRequestId && tx.signingRequestId !== signingRequestId)
|
|
227
|
+
throw new Error('Stable signing request identity mismatch');
|
|
228
|
+
const approvalSnapshot = deepFreeze({ context, transaction: planned, unsigned, signingRequestId });
|
|
229
|
+
return approved<EoaExecutionResult>(approvalSnapshot, async (assertApproval) => {
|
|
230
|
+
// Approval may await user interaction; revalidate chain and finalized prefix immediately before controlled signing/send.
|
|
231
|
+
await verifyPrefix(c, s);
|
|
232
|
+
await verifyEoaChain(provider, context);
|
|
233
|
+
await verifyEoaCode(provider, planned.executor, 'latest');
|
|
234
|
+
assertApproval();
|
|
235
|
+
if (tx.state === 'claimed') {
|
|
236
|
+
s = store.markSigning(c, s.revision, signingRequestId);
|
|
237
|
+
const raw = await signer.sign(signingRequestId, unsigned);
|
|
238
|
+
assertApproval();
|
|
239
|
+
s = store.commitSigned(c, s.revision, verifyEoaSigned(raw, unsigned));
|
|
240
|
+
}
|
|
241
|
+
else if (tx.state === 'signing') {
|
|
242
|
+
const recovered = await signer.recover?.(signingRequestId);
|
|
243
|
+
assertApproval();
|
|
244
|
+
if (recovered === undefined)
|
|
245
|
+
return { status: 'signing-result-unavailable', snapshot: s };
|
|
246
|
+
s = store.commitSigned(c, s.revision, verifyEoaSigned(recovered, unsigned));
|
|
247
|
+
}
|
|
248
|
+
tx = s.transactions[s.completedCount];
|
|
249
|
+
if (tx.state !== 'signed' || !tx.signed)
|
|
250
|
+
throw new Error('Original durable signed bytes required');
|
|
251
|
+
const signed = verifyEoaSigned(tx.signed.rawTransaction, unsigned);
|
|
252
|
+
if (!same(signed, tx.signed))
|
|
253
|
+
throw new Error('Durable signed identity mismatch');
|
|
254
|
+
await verifyPrefix(c, s);
|
|
255
|
+
await verifyEoaChain(provider, context);
|
|
256
|
+
await verifyEoaCode(provider, planned.executor, 'latest');
|
|
257
|
+
assertApproval();
|
|
258
|
+
s = store.recordSubmissionIntent(c, s.revision);
|
|
259
|
+
const returnedHash = await provider.request('eth_sendRawTransaction', [signed.rawTransaction]);
|
|
260
|
+
if (returnedHash !== signed.transactionHash)
|
|
261
|
+
throw new Error('Broadcast returned wrong hash; original submission remains uncertain');
|
|
262
|
+
return { status: 'submitted', snapshot: s };
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
},
|
|
266
|
+
async reconcile(references: EoaHashReferences = {}): Promise<EoaExecutionResult> {
|
|
267
|
+
// Copy only explicit data before any awaited calls; caller mutation cannot change the route/hash set.
|
|
268
|
+
const refs = deepFreeze(JSON.parse(JSON.stringify(references))) as EoaHashReferences;
|
|
269
|
+
for (const [id, hashes] of Object.entries(refs)) {
|
|
270
|
+
if (!plan.transactions.some(tx => tx.transactionId === id) || !Array.isArray(hashes))
|
|
271
|
+
throw new Error('Unknown transaction hash reference');
|
|
272
|
+
hashes.forEach(h => hash32(h, 'explicit transaction hash'));
|
|
273
|
+
}
|
|
274
|
+
return claim((c, s) => reconcileActive(c, s, refs));
|
|
275
|
+
},
|
|
276
|
+
/** Revalidates the durable contiguous prefix under the claim before producing trusted export progress. */
|
|
277
|
+
async export() {
|
|
278
|
+
return claim(async (c, s) => {
|
|
279
|
+
const completed = await verifyPrefix(c, s), byId = new Map(completed.map(o => [o.observationId, o]));
|
|
280
|
+
const progress = await validateDeliveryProgress({ plan, completed: completed.map(o => o.observationId), finalized: { readFinalized: async (ref) => byId.get(ref) } });
|
|
281
|
+
const exported = renderDeliveryExport(plan, progress);
|
|
282
|
+
const model = deepFreeze({ ...exported.model, safeEnvelopes: s.safeEnvelopes.map(e => renderSafeExport(plan, e).model), safePreparation: plan.transactions[s.completedCount]?.route !== 'external' ? 'not-applicable' : s.safeEnvelopes.some(e => e.start === s.completedCount) ? 'ready' : 'preparation-required' });
|
|
283
|
+
const json = JSON.stringify(model);
|
|
284
|
+
return deepFreeze({ model, json, markdown: `# Delivery calldata\n\nFrozen Safe envelopes cover only prepared segments. Future segments remain pending.\n\n\`\`\`json\n${json}\n\`\`\`\n` });
|
|
285
|
+
});
|
|
286
|
+
},
|
|
287
|
+
});
|
|
288
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import type { DatabaseSync } from 'node:sqlite';
|
|
4
|
+
import { type StoreFiles } from './execution-files';
|
|
5
|
+
export type Database = Pick<DatabaseSync, 'exec' | 'prepare' | 'close'>;
|
|
6
|
+
const marker = `CREATE TABLE protocol (version INTEGER PRIMARY KEY CHECK(version=1), kind TEXT NOT NULL, store_id TEXT NOT NULL, phase TEXT NOT NULL)`;
|
|
7
|
+
const tables = [
|
|
8
|
+
marker,
|
|
9
|
+
`CREATE TABLE executions (execution_id TEXT PRIMARY KEY, context_hash TEXT NOT NULL, plan_hash TEXT NOT NULL, plan_json TEXT NOT NULL, revision TEXT NOT NULL, epoch TEXT NOT NULL, active_transaction_id TEXT, completed_count INTEGER NOT NULL)`,
|
|
10
|
+
`CREATE TABLE transactions (execution_id TEXT NOT NULL REFERENCES executions(execution_id), transaction_id TEXT NOT NULL, transaction_index INTEGER NOT NULL, state TEXT NOT NULL, unsigned_json TEXT, unsigned_digest TEXT, signing_request_id TEXT, signed_json TEXT, observation_json TEXT, PRIMARY KEY(execution_id,transaction_id), UNIQUE(execution_id,transaction_index))`,
|
|
11
|
+
`CREATE TABLE nonce_reservations (chain_id TEXT NOT NULL, signer TEXT NOT NULL, nonce TEXT NOT NULL, execution_id TEXT NOT NULL, transaction_id TEXT NOT NULL, unsigned_digest TEXT NOT NULL, PRIMARY KEY(chain_id,signer,nonce), FOREIGN KEY(execution_id,transaction_id) REFERENCES transactions(execution_id,transaction_id))`
|
|
12
|
+
];
|
|
13
|
+
const previousTables = [...tables];
|
|
14
|
+
tables[1] = tables[1].replace('completed_count INTEGER NOT NULL)', 'completed_count INTEGER NOT NULL, blocked_reason TEXT)');
|
|
15
|
+
const v2Tables = [...tables];
|
|
16
|
+
tables.push(`CREATE TABLE safe_envelopes (execution_id TEXT NOT NULL REFERENCES executions(execution_id), envelope_id TEXT PRIMARY KEY, start_index INTEGER NOT NULL, envelope_json TEXT NOT NULL, chain_id TEXT NOT NULL, safe_address TEXT NOT NULL, safe_nonce TEXT NOT NULL, outer_hash TEXT, UNIQUE(execution_id,start_index), UNIQUE(chain_id,safe_address,safe_nonce), UNIQUE(chain_id,outer_hash))`);
|
|
17
|
+
const normalize = (s: string) => s.replace(/\s+/g, ' ').trim();
|
|
18
|
+
/** Entry-specific runtime guard, before loading node:sqlite. Global package engines are separate. */
|
|
19
|
+
export function assertExecutionRuntime(version = process.versions.node): void {
|
|
20
|
+
if (!/^(?:22\.(?:1[3-9]|[2-9][0-9]|[1-9][0-9]{2,})\.\d+|24\.\d+\.\d+)$/.test(version))
|
|
21
|
+
throw new Error('Durable delivery execution requires Node ^22.13.0 || ^24.0.0');
|
|
22
|
+
}
|
|
23
|
+
export async function sqliteConstructor(): Promise<typeof DatabaseSync> { assertExecutionRuntime(); return (await import('node:sqlite')).DatabaseSync; }
|
|
24
|
+
export function configure(db: Database, busyTimeout: number): void {
|
|
25
|
+
db.exec(`PRAGMA busy_timeout=${busyTimeout}; PRAGMA foreign_keys=ON`);
|
|
26
|
+
const mode = db.prepare('PRAGMA journal_mode').get() as {
|
|
27
|
+
journal_mode: string;
|
|
28
|
+
};
|
|
29
|
+
if (mode.journal_mode.toLowerCase() !== 'delete')
|
|
30
|
+
throw new Error('Unsupported store journal mode; DELETE required');
|
|
31
|
+
db.exec('PRAGMA synchronous=EXTRA');
|
|
32
|
+
if (process.platform === 'darwin')
|
|
33
|
+
db.exec('PRAGMA fullfsync=ON');
|
|
34
|
+
}
|
|
35
|
+
/** Synchronous SQL only. A committed-but-unsynced result is uncertain and must be reread. */
|
|
36
|
+
export function commit<T>(db: Database, files: StoreFiles, work: () => T): T {
|
|
37
|
+
files.verify();
|
|
38
|
+
db.exec('BEGIN IMMEDIATE');
|
|
39
|
+
let committed = false;
|
|
40
|
+
try {
|
|
41
|
+
const value = work();
|
|
42
|
+
if (value && typeof (value as {
|
|
43
|
+
then?: unknown;
|
|
44
|
+
}).then === 'function')
|
|
45
|
+
throw new Error('Async work is forbidden inside a SQL transaction');
|
|
46
|
+
files.verify();
|
|
47
|
+
db.exec('COMMIT');
|
|
48
|
+
committed = true;
|
|
49
|
+
files.sync();
|
|
50
|
+
return value;
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
if (!committed) {
|
|
54
|
+
try {
|
|
55
|
+
db.exec('ROLLBACK');
|
|
56
|
+
}
|
|
57
|
+
catch { }
|
|
58
|
+
}
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
interface Protocol {
|
|
63
|
+
version: number;
|
|
64
|
+
kind: string;
|
|
65
|
+
store_id: string;
|
|
66
|
+
phase: 'initializing' | 'ready';
|
|
67
|
+
}
|
|
68
|
+
function readSchema(db: Database, kind: 'authority' | 'execution', allowCreate: boolean, storeId?: string): Protocol {
|
|
69
|
+
const expected = kind === 'authority' ? [marker] : tables;
|
|
70
|
+
let rows = db.prepare("SELECT sql FROM sqlite_master WHERE name NOT LIKE 'sqlite_%' ORDER BY name").all() as {
|
|
71
|
+
sql: string;
|
|
72
|
+
}[];
|
|
73
|
+
let version = Number((db.prepare('PRAGMA user_version').get() as {
|
|
74
|
+
user_version: number;
|
|
75
|
+
}).user_version);
|
|
76
|
+
const targetVersion = kind === 'authority' ? 1 : 3;
|
|
77
|
+
if (kind === 'execution' && version === 1 && JSON.stringify(rows.map(r => normalize(r.sql)).sort()) === JSON.stringify(previousTables.map(normalize).sort())) {
|
|
78
|
+
db.exec('ALTER TABLE executions ADD COLUMN blocked_reason TEXT');
|
|
79
|
+
db.exec('PRAGMA user_version=2');
|
|
80
|
+
version = 2;
|
|
81
|
+
rows = db.prepare("SELECT sql FROM sqlite_master WHERE name NOT LIKE 'sqlite_%' ORDER BY name").all() as {
|
|
82
|
+
sql: string;
|
|
83
|
+
}[];
|
|
84
|
+
}
|
|
85
|
+
if (kind === 'execution' && version === 2 && JSON.stringify(rows.map(r => normalize(r.sql)).sort()) === JSON.stringify(v2Tables.map(normalize).sort())) {
|
|
86
|
+
db.exec(tables[tables.length - 1]);
|
|
87
|
+
db.exec('PRAGMA user_version=3');
|
|
88
|
+
version = 3;
|
|
89
|
+
rows = db.prepare("SELECT sql FROM sqlite_master WHERE name NOT LIKE 'sqlite_%' ORDER BY name").all() as {
|
|
90
|
+
sql: string;
|
|
91
|
+
}[];
|
|
92
|
+
}
|
|
93
|
+
if (rows.length === 0 && version === 0) {
|
|
94
|
+
if (!allowCreate)
|
|
95
|
+
throw new Error('Ready store cannot recreate a pristine business schema');
|
|
96
|
+
for (const sql of expected)
|
|
97
|
+
db.exec(sql);
|
|
98
|
+
db.prepare('INSERT INTO protocol(version,kind,store_id,phase) VALUES(1,?,?,?)').run(kind, storeId ?? randomUUID(), kind === 'authority' ? 'initializing' : 'ready');
|
|
99
|
+
db.exec(`PRAGMA user_version=${targetVersion}`);
|
|
100
|
+
rows = db.prepare("SELECT sql FROM sqlite_master WHERE name NOT LIKE 'sqlite_%' ORDER BY name").all() as {
|
|
101
|
+
sql: string;
|
|
102
|
+
}[];
|
|
103
|
+
}
|
|
104
|
+
else if (version !== targetVersion)
|
|
105
|
+
throw new Error('Unknown store schema version');
|
|
106
|
+
if (JSON.stringify(rows.map(r => normalize(r.sql)).sort()) !== JSON.stringify(expected.map(normalize).sort()))
|
|
107
|
+
throw new Error('Unknown store schema');
|
|
108
|
+
const protocol = db.prepare('SELECT * FROM protocol').all() as unknown as Protocol[];
|
|
109
|
+
if (protocol.length !== 1 || protocol[0].version !== 1 || protocol[0].kind !== kind || !(/^[0-9a-f-]{36}$/.test(protocol[0].store_id)) || !['initializing', 'ready'].includes(protocol[0].phase))
|
|
110
|
+
throw new Error('Unknown store protocol marker');
|
|
111
|
+
if (storeId !== undefined && protocol[0].store_id !== storeId)
|
|
112
|
+
throw new Error('Store UUID identity mismatch');
|
|
113
|
+
return protocol[0];
|
|
114
|
+
}
|
|
115
|
+
/** Bootstrap marker commits before business creation. No execution work is allowed until both UUIDs
|
|
116
|
+
* are synced and the authority marker is ready. A ready marker never reinitializes business data. */
|
|
117
|
+
export function bootstrapAuthority(db: Database, files: StoreFiles): Protocol {
|
|
118
|
+
return commit(db, files, () => readSchema(db, 'authority', !fs.existsSync(files.execution) || fs.statSync(files.execution).size === 0));
|
|
119
|
+
}
|
|
120
|
+
export function initializeBusiness(authority: Database, business: Database, files: StoreFiles, protocol: Protocol): void {
|
|
121
|
+
commit(business, files, () => {
|
|
122
|
+
const p = readSchema(business, 'execution', protocol.phase === 'initializing', protocol.store_id);
|
|
123
|
+
if (p.phase !== 'ready')
|
|
124
|
+
throw new Error('Invalid business bootstrap phase');
|
|
125
|
+
});
|
|
126
|
+
if (protocol.phase === 'initializing') {
|
|
127
|
+
const result = authority.prepare("UPDATE protocol SET phase='ready' WHERE version=1 AND store_id=? AND phase='initializing'").run(protocol.store_id);
|
|
128
|
+
if (BigInt(result.changes) !== 1n)
|
|
129
|
+
throw new Error('Bootstrap marker CAS conflict');
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/** Fixed private local store paths. Callers supply the shared host/CLI anchor, never a project cache. */
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
export interface StoreFiles {
|
|
5
|
+
root: string;
|
|
6
|
+
authority: string;
|
|
7
|
+
execution: string;
|
|
8
|
+
verify(): void;
|
|
9
|
+
sync(): void;
|
|
10
|
+
ensureExecution(allowCreate: boolean): void;
|
|
11
|
+
}
|
|
12
|
+
function stat(name: string): fs.Stats | undefined { try {
|
|
13
|
+
return fs.lstatSync(name);
|
|
14
|
+
}
|
|
15
|
+
catch (e) {
|
|
16
|
+
if ((e as NodeJS.ErrnoException).code === 'ENOENT')
|
|
17
|
+
return;
|
|
18
|
+
throw e;
|
|
19
|
+
} }
|
|
20
|
+
function owner(s: fs.Stats): boolean { return process.getuid === undefined || s.uid === process.getuid(); }
|
|
21
|
+
function directory(name: string, privateDir = false): fs.Stats {
|
|
22
|
+
const s = fs.lstatSync(name);
|
|
23
|
+
if (!s.isDirectory() || s.isSymbolicLink())
|
|
24
|
+
throw new Error('Store path has a non-directory or symlink component');
|
|
25
|
+
if (privateDir && (!owner(s) || (s.mode & 0o777) !== 0o700))
|
|
26
|
+
throw new Error('Store root must be private 0700 and owned by this user');
|
|
27
|
+
return s;
|
|
28
|
+
}
|
|
29
|
+
function components(name: string): void {
|
|
30
|
+
const parts = name.split(path.sep);
|
|
31
|
+
let current = path.parse(name).root;
|
|
32
|
+
for (const part of parts.filter(Boolean)) {
|
|
33
|
+
current = path.join(current, part);
|
|
34
|
+
directory(current);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function syncDirectory(name: string): void {
|
|
38
|
+
const fd = fs.openSync(name, fs.constants.O_RDONLY | fs.constants.O_DIRECTORY | fs.constants.O_NOFOLLOW);
|
|
39
|
+
try {
|
|
40
|
+
fs.fsyncSync(fd);
|
|
41
|
+
}
|
|
42
|
+
finally {
|
|
43
|
+
fs.closeSync(fd);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function file(name: string): fs.Stats {
|
|
47
|
+
const s = fs.lstatSync(name);
|
|
48
|
+
if (!s.isFile() || s.isSymbolicLink() || s.nlink !== 1 || !owner(s) || (s.mode & 0o777) !== 0o600)
|
|
49
|
+
throw new Error('Store database/side file must be regular private 0600, owned, with one link');
|
|
50
|
+
return s;
|
|
51
|
+
}
|
|
52
|
+
function create(name: string): void {
|
|
53
|
+
let fd: number;
|
|
54
|
+
try {
|
|
55
|
+
fd = fs.openSync(name, fs.constants.O_CREAT | fs.constants.O_EXCL | fs.constants.O_WRONLY | fs.constants.O_NOFOLLOW, 0o600);
|
|
56
|
+
}
|
|
57
|
+
catch (e) {
|
|
58
|
+
if ((e as NodeJS.ErrnoException).code === 'EEXIST') {
|
|
59
|
+
file(name);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
throw e;
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
fs.fsyncSync(fd);
|
|
66
|
+
}
|
|
67
|
+
finally {
|
|
68
|
+
fs.closeSync(fd);
|
|
69
|
+
}
|
|
70
|
+
syncDirectory(path.dirname(name));
|
|
71
|
+
}
|
|
72
|
+
export function prepareStoreFiles(root: string): StoreFiles {
|
|
73
|
+
if (typeof root !== 'string' || !path.isAbsolute(root) || root !== path.normalize(root) || root.split(path.sep).some(p => p === '.' || p === '..'))
|
|
74
|
+
throw new Error('Trusted store root must be a canonical absolute path');
|
|
75
|
+
if (!stat(root)) {
|
|
76
|
+
components(path.dirname(root));
|
|
77
|
+
directory(path.dirname(root), true);
|
|
78
|
+
try {
|
|
79
|
+
fs.mkdirSync(root, { mode: 0o700 });
|
|
80
|
+
}
|
|
81
|
+
catch (e) {
|
|
82
|
+
if ((e as NodeJS.ErrnoException).code !== 'EEXIST')
|
|
83
|
+
throw e;
|
|
84
|
+
}
|
|
85
|
+
syncDirectory(path.dirname(root));
|
|
86
|
+
}
|
|
87
|
+
components(root);
|
|
88
|
+
const anchor = directory(root, true);
|
|
89
|
+
const authority = path.join(root, 'authority.sqlite'), execution = path.join(root, 'execution.sqlite');
|
|
90
|
+
const sideFiles = () => {
|
|
91
|
+
for (const db of [authority, execution]) {
|
|
92
|
+
for (const suffix of ['-wal', '-shm'])
|
|
93
|
+
if (stat(db + suffix))
|
|
94
|
+
throw new Error('Unexpected WAL side file');
|
|
95
|
+
if (stat(db + '-journal'))
|
|
96
|
+
file(db + '-journal'); // SQLite alone recovers hot rollback journals.
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
sideFiles();
|
|
100
|
+
if (!stat(authority) && stat(execution))
|
|
101
|
+
throw new Error('Established store authority database is missing');
|
|
102
|
+
create(authority);
|
|
103
|
+
const a = file(authority);
|
|
104
|
+
let b = stat(execution) ? file(execution) : undefined;
|
|
105
|
+
const distinct = () => { if (b && a.dev === b.dev && a.ino === b.ino)
|
|
106
|
+
throw new Error('Database inode alias'); };
|
|
107
|
+
distinct();
|
|
108
|
+
const verify = () => {
|
|
109
|
+
components(root);
|
|
110
|
+
const d = directory(root, true);
|
|
111
|
+
if (d.dev !== anchor.dev || d.ino !== anchor.ino)
|
|
112
|
+
throw new Error('Store root inode changed');
|
|
113
|
+
sideFiles();
|
|
114
|
+
for (const [name, original] of [[authority, a], [execution, b]] as const) {
|
|
115
|
+
if (!original) {
|
|
116
|
+
if (stat(name))
|
|
117
|
+
throw new Error("Unexpected database appeared before bootstrap");
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
const s = file(name);
|
|
121
|
+
if (s.dev !== original.dev || s.ino !== original.ino)
|
|
122
|
+
throw new Error('Store database inode changed');
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
return { root, authority, execution, verify, ensureExecution(allowCreate) {
|
|
126
|
+
if (!b) {
|
|
127
|
+
if (!allowCreate)
|
|
128
|
+
throw new Error('Ready store business database is missing');
|
|
129
|
+
create(execution);
|
|
130
|
+
b = file(execution);
|
|
131
|
+
distinct();
|
|
132
|
+
}
|
|
133
|
+
verify();
|
|
134
|
+
}, sync() { verify(); syncDirectory(root); verify(); } };
|
|
135
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { canonicalJson, deepFreeze, digest, exactObject, semanticHash } from '../workflow/lib/canonicalData';
|
|
2
|
+
import { strictData } from './data';
|
|
3
|
+
import type { DeliveryPlan } from './plan';
|
|
4
|
+
import type { SafeEnvelope } from './safe';
|
|
5
|
+
import { uint256, hash32, type TransactionObservation } from './observations';
|
|
6
|
+
export type TransactionState = 'claimed' | 'signing' | 'signed' | 'submission-uncertain' | 'included-unfinalized' | 'finalized-success' | 'finalized-reverted' | 'blocked';
|
|
7
|
+
export interface UnsignedEnvelope {
|
|
8
|
+
chainId: string;
|
|
9
|
+
signer: string;
|
|
10
|
+
nonce: string;
|
|
11
|
+
to: string;
|
|
12
|
+
value: string;
|
|
13
|
+
data: string;
|
|
14
|
+
operation: 0 | 1;
|
|
15
|
+
type: 0 | 1 | 2;
|
|
16
|
+
gasLimit: string;
|
|
17
|
+
gasPrice: string | null;
|
|
18
|
+
maxFeePerGas: string | null;
|
|
19
|
+
maxPriorityFeePerGas: string | null;
|
|
20
|
+
accessList: {
|
|
21
|
+
address: string;
|
|
22
|
+
storageKeys: string[];
|
|
23
|
+
}[];
|
|
24
|
+
}
|
|
25
|
+
/** A durable byte record, deliberately not a signature-validation or send-authorization capability. */
|
|
26
|
+
export interface SignedRecord {
|
|
27
|
+
rawTransaction: string;
|
|
28
|
+
transactionHash: string;
|
|
29
|
+
unsignedDigest: string;
|
|
30
|
+
}
|
|
31
|
+
export interface TransactionRecord {
|
|
32
|
+
transactionId: string;
|
|
33
|
+
index: number;
|
|
34
|
+
state: TransactionState;
|
|
35
|
+
unsigned: UnsignedEnvelope | null;
|
|
36
|
+
unsignedDigest: string | null;
|
|
37
|
+
signingRequestId: string | null;
|
|
38
|
+
signed: SignedRecord | null;
|
|
39
|
+
observation: TransactionObservation | null;
|
|
40
|
+
}
|
|
41
|
+
export interface ExecutionSnapshot {
|
|
42
|
+
executionId: string;
|
|
43
|
+
contextHash: string;
|
|
44
|
+
planHash: string;
|
|
45
|
+
plan: DeliveryPlan;
|
|
46
|
+
revision: string;
|
|
47
|
+
epoch: string;
|
|
48
|
+
activeTransactionId: string | null;
|
|
49
|
+
completedCount: number;
|
|
50
|
+
blockedReason: string | null;
|
|
51
|
+
transactions: TransactionRecord[];
|
|
52
|
+
safeEnvelopes: SafeEnvelope[];
|
|
53
|
+
}
|
|
54
|
+
export function decimal(raw: unknown, label: string): string { if (typeof raw !== 'string' || !/^(0|[1-9][0-9]*)$/.test(raw))
|
|
55
|
+
throw new Error(`Invalid ${label}`); return raw; }
|
|
56
|
+
function address(v: unknown): string { if (typeof v !== 'string' || !/^0x[0-9a-f]{40}$/.test(v))
|
|
57
|
+
throw new Error('Expected normalized signer/address'); return v; }
|
|
58
|
+
export function parseUnsigned(raw: unknown, plan: DeliveryPlan, index: number): UnsignedEnvelope {
|
|
59
|
+
const v = exactObject(strictData(raw), ['chainId', 'signer', 'nonce', 'to', 'value', 'data', 'operation', 'type', 'gasLimit', 'gasPrice', 'maxFeePerGas', 'maxPriorityFeePerGas', 'accessList'], 'unsigned envelope');
|
|
60
|
+
for (const key of ['chainId', 'nonce', 'value', 'gasLimit'])
|
|
61
|
+
uint256(v[key], key);
|
|
62
|
+
address(v.signer);
|
|
63
|
+
address(v.to);
|
|
64
|
+
const tx = plan.transactions[index];
|
|
65
|
+
if (!tx || v.chainId !== plan.chainId || v.signer !== tx.executor || v.to !== tx.to || v.value !== tx.value || v.data !== tx.data || v.operation !== tx.operation)
|
|
66
|
+
throw new Error('Unsigned envelope differs from immutable transaction');
|
|
67
|
+
if (![0, 1, 2].includes(v.type as number))
|
|
68
|
+
throw new Error('Unsupported transaction type');
|
|
69
|
+
if (v.type === 2) {
|
|
70
|
+
uint256(v.maxFeePerGas, 'maxFeePerGas');
|
|
71
|
+
uint256(v.maxPriorityFeePerGas, 'maxPriorityFeePerGas');
|
|
72
|
+
if (v.gasPrice !== null || BigInt(v.maxPriorityFeePerGas as string) > BigInt(v.maxFeePerGas as string))
|
|
73
|
+
throw new Error('Invalid EIP-1559 fees');
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
uint256(v.gasPrice, 'gasPrice');
|
|
77
|
+
if (v.maxFeePerGas !== null || v.maxPriorityFeePerGas !== null)
|
|
78
|
+
throw new Error('Invalid legacy fees');
|
|
79
|
+
}
|
|
80
|
+
if (!Array.isArray(v.accessList) || (v.type === 0 && v.accessList.length))
|
|
81
|
+
throw new Error('Invalid access list');
|
|
82
|
+
for (const item of v.accessList) {
|
|
83
|
+
const a = exactObject(item, ['address', 'storageKeys'], 'access list');
|
|
84
|
+
address(a.address);
|
|
85
|
+
if (!Array.isArray(a.storageKeys))
|
|
86
|
+
throw new Error('Invalid storage keys');
|
|
87
|
+
a.storageKeys.forEach(k => hash32(k, 'storage key'));
|
|
88
|
+
}
|
|
89
|
+
return deepFreeze(v as unknown as UnsignedEnvelope);
|
|
90
|
+
}
|
|
91
|
+
export function unsignedHash(envelope: UnsignedEnvelope): string { return semanticHash({ schema: 'gate-unsigned-envelope', version: 1, envelope }); }
|
|
92
|
+
export function parseSigned(raw: unknown, unsignedDigest: string): SignedRecord {
|
|
93
|
+
const v = exactObject(strictData(raw), ['rawTransaction', 'transactionHash', 'unsignedDigest'], 'signed record');
|
|
94
|
+
if (typeof v.rawTransaction !== 'string' || !/^0x(?:[0-9a-f]{2})+$/.test(v.rawTransaction))
|
|
95
|
+
throw new Error('Invalid raw signed bytes');
|
|
96
|
+
hash32(v.transactionHash, 'signed transaction hash');
|
|
97
|
+
digest(v.unsignedDigest, 'unsigned');
|
|
98
|
+
if (v.unsignedDigest !== unsignedDigest)
|
|
99
|
+
throw new Error('Signed unsigned digest mismatch');
|
|
100
|
+
return deepFreeze(v as unknown as SignedRecord);
|
|
101
|
+
}
|
|
102
|
+
export function same(a: unknown, b: unknown): boolean { return canonicalJson(a) === canonicalJson(b); }
|