gate-evm-tools 1.2.1 → 1.2.2
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 +6 -2
- package/bin/cli.js +3 -0
- package/bin/delivery.cjs +11 -6
- package/bin/migration.js +38 -0
- package/dist/commands/prepare.d.ts.map +1 -1
- package/dist/commands/prepare.js +7 -1
- package/dist/commands/prepare.js.map +1 -1
- package/dist/core/BytecodeChecker.d.ts.map +1 -1
- package/dist/core/BytecodeChecker.js +27 -4
- package/dist/core/BytecodeChecker.js.map +1 -1
- package/dist/core/preparation/artifacts.d.ts.map +1 -1
- package/dist/core/preparation/artifacts.js +12 -5
- package/dist/core/preparation/artifacts.js.map +1 -1
- package/dist/core/preparation/index.d.ts +3 -0
- package/dist/core/preparation/index.d.ts.map +1 -1
- package/dist/core/preparation/index.js +9 -2
- package/dist/core/preparation/index.js.map +1 -1
- package/dist/core/preparation/zksync.d.ts.map +1 -1
- package/dist/core/preparation/zksync.js +5 -0
- package/dist/core/preparation/zksync.js.map +1 -1
- package/dist/core/validateAndGenerateCalldata.d.ts.map +1 -1
- package/dist/core/validateAndGenerateCalldata.js +3 -0
- package/dist/core/validateAndGenerateCalldata.js.map +1 -1
- package/dist/deployment-zksync/index.d.ts +40 -0
- package/dist/deployment-zksync/index.d.ts.map +1 -0
- package/dist/deployment-zksync/index.js +59 -0
- package/dist/deployment-zksync/index.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -12
- package/dist/index.js.map +1 -1
- package/dist/migration/index.d.ts +76 -0
- package/dist/migration/index.d.ts.map +1 -0
- package/dist/migration/index.js +284 -0
- package/dist/migration/index.js.map +1 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/dist-cjs/core/BytecodeChecker.js +27 -4
- package/dist-cjs/core/BytecodeChecker.js.map +1 -1
- package/dist-cjs/core/preparation/artifacts.js +11 -4
- package/dist-cjs/core/preparation/artifacts.js.map +1 -1
- package/dist-cjs/core/preparation/index.js +47 -6
- package/dist-cjs/core/preparation/index.js.map +1 -1
- package/dist-cjs/core/preparation/zksync.js +5 -0
- package/dist-cjs/core/preparation/zksync.js.map +1 -1
- package/dist-cjs/deployment-zksync/index.js +67 -0
- package/dist-cjs/deployment-zksync/index.js.map +1 -0
- package/dist-cjs/migration/index.js +328 -0
- package/dist-cjs/migration/index.js.map +1 -0
- package/dist-runtime/delivery/aggregate-diagnostics.js +3 -0
- package/dist-runtime/delivery/aggregate-diagnostics.js.map +1 -1
- package/dist-runtime/delivery/aggregate-inputs.d.ts +32 -6
- package/dist-runtime/delivery/aggregate-inputs.js +7 -3
- package/dist-runtime/delivery/aggregate-inputs.js.map +1 -1
- package/dist-runtime/delivery/aggregate-worker.js +3 -3
- package/dist-runtime/delivery/aggregate-worker.js.map +1 -1
- package/dist-runtime/delivery/aggregate.js +2 -2
- package/dist-runtime/delivery/aggregate.js.map +1 -1
- package/dist-runtime/delivery/cli-host.d.ts +17 -0
- package/dist-runtime/delivery/cli-host.js +118 -0
- package/dist-runtime/delivery/cli-host.js.map +1 -0
- package/dist-runtime/delivery/cli.d.ts +114 -0
- package/dist-runtime/delivery/cli.js +228 -0
- package/dist-runtime/delivery/cli.js.map +1 -0
- package/dist-runtime/delivery/compiler-dependency-pins.js +30 -1
- package/dist-runtime/delivery/compiler-dependency-pins.js.map +1 -1
- package/dist-runtime/delivery/configuration-definition.js +152 -11
- package/dist-runtime/delivery/configuration-definition.js.map +1 -1
- package/dist-runtime/delivery/configuration-hre.js +1 -1
- package/dist-runtime/delivery/configuration-hre.js.map +1 -1
- package/dist-runtime/delivery/configuration.js +7 -4
- package/dist-runtime/delivery/configuration.js.map +1 -1
- package/dist-runtime/delivery/custom-format.d.ts +2 -1
- package/dist-runtime/delivery/custom-format.js +15 -2
- package/dist-runtime/delivery/custom-format.js.map +1 -1
- package/dist-runtime/delivery/custom.d.ts +4 -0
- package/dist-runtime/delivery/custom.js +21 -0
- package/dist-runtime/delivery/custom.js.map +1 -1
- package/dist-runtime/delivery/development-inputs.d.ts +9 -0
- package/dist-runtime/delivery/development-inputs.js +41 -0
- package/dist-runtime/delivery/development-inputs.js.map +1 -1
- package/dist-runtime/delivery/development.d.ts +1 -1
- package/dist-runtime/delivery/development.js +5 -2
- package/dist-runtime/delivery/development.js.map +1 -1
- package/dist-runtime/delivery/execution-records.d.ts +16 -0
- package/dist-runtime/delivery/execution-records.js +48 -0
- package/dist-runtime/delivery/execution-records.js.map +1 -0
- package/dist-runtime/delivery/existing-code.d.ts +3 -0
- package/dist-runtime/delivery/existing-code.js +20 -0
- package/dist-runtime/delivery/existing-code.js.map +1 -1
- package/dist-runtime/delivery/input-files.d.ts +2 -0
- package/dist-runtime/delivery/input-files.js +5 -0
- package/dist-runtime/delivery/input-files.js.map +1 -1
- package/dist-runtime/delivery/inputs.js +11 -6
- package/dist-runtime/delivery/inputs.js.map +1 -1
- package/dist-runtime/delivery/materialization.js +20 -1
- package/dist-runtime/delivery/materialization.js.map +1 -1
- package/dist-runtime/delivery/planning.d.ts +1 -0
- package/dist-runtime/delivery/planning.js +10 -2
- package/dist-runtime/delivery/planning.js.map +1 -1
- package/dist-runtime/delivery/production-finalization.js +3 -2
- package/dist-runtime/delivery/production-finalization.js.map +1 -1
- package/dist-runtime/delivery/production.d.ts +2 -0
- package/dist-runtime/delivery/production.js +5 -4
- package/dist-runtime/delivery/production.js.map +1 -1
- package/dist-runtime/delivery/project-files.js +6 -1
- package/dist-runtime/delivery/project-files.js.map +1 -1
- package/dist-runtime/delivery/project-rpc.d.ts +1 -1
- package/dist-runtime/delivery/project-rpc.js +10 -4
- package/dist-runtime/delivery/project-rpc.js.map +1 -1
- package/dist-runtime/delivery/protocol.d.ts +6 -4
- package/dist-runtime/delivery/protocol.js +16 -5
- package/dist-runtime/delivery/protocol.js.map +1 -1
- package/dist-runtime/delivery/query.d.ts +21 -0
- package/dist-runtime/delivery/query.js +58 -0
- package/dist-runtime/delivery/query.js.map +1 -0
- package/dist-runtime/delivery/release-graph.d.ts +17 -0
- package/dist-runtime/delivery/release-graph.js +23 -0
- package/dist-runtime/delivery/release-graph.js.map +1 -1
- package/dist-runtime/delivery/release-history-capture.js +5 -2
- package/dist-runtime/delivery/release-history-capture.js.map +1 -1
- package/dist-runtime/delivery/release-history.js +19 -12
- package/dist-runtime/delivery/release-history.js.map +1 -1
- package/dist-runtime/delivery/release.d.ts +22 -0
- package/dist-runtime/delivery/release.js +13 -3
- package/dist-runtime/delivery/release.js.map +1 -1
- package/dist-runtime/delivery/scripts.d.ts +116 -0
- package/dist-runtime/delivery/scripts.js +289 -0
- package/dist-runtime/delivery/scripts.js.map +1 -0
- package/dist-runtime/delivery/setup.d.ts +1 -1
- package/dist-runtime/delivery/setup.js +26 -36
- package/dist-runtime/delivery/setup.js.map +1 -1
- package/dist-runtime/delivery/source.d.ts +5 -2
- package/dist-runtime/delivery/source.js +4 -3
- package/dist-runtime/delivery/source.js.map +1 -1
- package/dist-runtime/delivery/standalone-source.d.ts +40 -0
- package/dist-runtime/delivery/standalone-source.js +54 -0
- package/dist-runtime/delivery/standalone-source.js.map +1 -0
- package/dist-runtime/runtime-identity.json +2 -2
- package/dist-runtime/workflow/lib/calls.js +21 -1
- package/dist-runtime/workflow/lib/calls.js.map +1 -1
- package/docs/configuration-runtime-observation.md +4 -2
- package/docs/delivery-custom-input-closure.md +2 -0
- package/docs/delivery-development.md +2 -0
- package/docs/delivery-inputs.md +2 -0
- package/docs/delivery-release.md +3 -1
- package/docs/delivery-setup.md +25 -20
- package/docs/delivery-source.md +4 -2
- package/docs/migration.md +108 -0
- package/docs/script-execution.md +85 -0
- package/package.json +42 -19
- package/runtime/delivery/aggregate-diagnostics.ts +2 -0
- package/runtime/delivery/aggregate-inputs.ts +6 -5
- package/runtime/delivery/aggregate-worker.ts +3 -3
- package/runtime/delivery/aggregate.ts +2 -2
- package/runtime/delivery/cli-host.ts +55 -0
- package/runtime/delivery/cli.ts +124 -0
- package/runtime/delivery/compiler-dependency-pins.ts +30 -1
- package/runtime/delivery/configuration-definition.ts +80 -9
- package/runtime/delivery/configuration-hre.ts +1 -1
- package/runtime/delivery/configuration.ts +7 -5
- package/runtime/delivery/custom-format.ts +11 -3
- package/runtime/delivery/custom.ts +13 -0
- package/runtime/delivery/development-inputs.ts +31 -0
- package/runtime/delivery/development.ts +4 -3
- package/runtime/delivery/execution-records.ts +31 -0
- package/runtime/delivery/existing-code.ts +12 -1
- package/runtime/delivery/input-files.ts +5 -1
- package/runtime/delivery/inputs.ts +10 -6
- package/runtime/delivery/materialization.ts +8 -1
- package/runtime/delivery/planning.ts +10 -2
- package/runtime/delivery/production-finalization.ts +3 -2
- package/runtime/delivery/production.ts +5 -4
- package/runtime/delivery/project-files.ts +5 -1
- package/runtime/delivery/project-rpc.ts +10 -4
- package/runtime/delivery/protocol.ts +13 -5
- package/runtime/delivery/query.ts +34 -0
- package/runtime/delivery/release-graph.ts +17 -0
- package/runtime/delivery/release-history-capture.ts +2 -1
- package/runtime/delivery/release-history.ts +8 -3
- package/runtime/delivery/release.ts +7 -4
- package/runtime/delivery/scripts.ts +162 -0
- package/runtime/delivery/setup.ts +21 -31
- package/runtime/delivery/source.ts +7 -3
- package/runtime/delivery/standalone-source.ts +40 -0
- package/runtime/workflow/lib/calls.ts +19 -1
- package/dist-runtime/delivery/toolchain.d.ts +0 -3
- package/dist-runtime/delivery/toolchain.js +0 -52
- package/dist-runtime/delivery/toolchain.js.map +0 -1
- package/runtime/delivery/toolchain.ts +0 -48
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Business scripts and delivery execution
|
|
2
|
+
|
|
3
|
+
Use the project's locked `gate-evm-tools` version. App and terminal hosts use the same parameter, simulation, ABI, transaction and durable execution kernel. A terminal run does not require App state, a GateFlow handoff, or an installed skill.
|
|
4
|
+
|
|
5
|
+
## Files and identities
|
|
6
|
+
|
|
7
|
+
Reusable business modules belong in `scripts/operations/`; helpers and synchronous `produce(inputs)` modules may live beside them. Each new business request creates `scripts/tasks/<deploymentId>/`. That directory owns `task.yaml`, `manifest.yaml`, `parameters.schema.json`, `parameters.yaml`, `parameters.provenance.json`, optional `inputs/` and `producers/`, and existing release/result/delivery records. New settings, redeployments and completed-operation repetitions use new deployment IDs. Recovery consumes the original execution ID and immutable input identity.
|
|
8
|
+
|
|
9
|
+
Native task metadata uses version 2 and `source: standalone`; requests use version 2 with `sourceRef: {kind: standalone, path, deploymentId}`. GateFlow keeps its actual task/requirement/revision checks. These adapters produce a common scope and input definition. Neither file metadata nor a JSON boolean grants signing approval.
|
|
10
|
+
|
|
11
|
+
Preparation captures the actual script/import/input bytes. Dev preparations retain `.gate-delivery/development/<executionId>.inputs.snapshot.json`; historical acceptance and production inputs use the existing archival protocol. Digests of selected scope, configuration, ABI and module closure are bound into the plan. Later edits cannot alter a resumed transaction. Signing does not run the business script or fetch new business inputs.
|
|
12
|
+
|
|
13
|
+
## Script protocol v1
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import type { DeliveryScript, ScriptPorts, ScriptInvocation } from 'gate-evm-tools/delivery-scripts';
|
|
17
|
+
export const delivery: DeliveryScript = {
|
|
18
|
+
version: 1,
|
|
19
|
+
description: 'Configure the explicitly requested value',
|
|
20
|
+
inputSchema: {
|
|
21
|
+
type: 'object', additionalProperties: false,
|
|
22
|
+
properties: { address: {type:'string'}, value: {type:'string',pattern:'^[0-9]+$'} },
|
|
23
|
+
required: ['address','value']
|
|
24
|
+
},
|
|
25
|
+
steps: [{ id: 'set-value' }]
|
|
26
|
+
};
|
|
27
|
+
export function planOperations(p: ScriptPorts, input: ScriptInvocation) {
|
|
28
|
+
if (input.stepId !== 'set-value') throw new Error('Unknown selected step');
|
|
29
|
+
const address = p.resolve('param.address'), value = p.resolve('param.value');
|
|
30
|
+
return {version:1, operations:[
|
|
31
|
+
{id:'set',kind:'call',name:'Set Vault value',description:'Set the confirmed Vault value',contract:'Vault',address,calls:[{method:'set(uint256)',args:[value]}]},
|
|
32
|
+
{id:'verify',kind:'check',contract:'Vault',address,calls:[{method:'value()',expect:value}]}
|
|
33
|
+
]};
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Use the supported deterministic TS/CommonJS subset. Business modules receive no filesystem, network, clock, environment, provider, HRE, signer or broadcasting capability. Imports are captured by the bounded loader; type-only SDK imports erase during transpilation. Simple native manifest calls need no business TS wrapper. CREATE2, placeholder proxies, upgrades and multicall use existing native operations; do not reimplement their transaction algorithms.
|
|
38
|
+
|
|
39
|
+
Dynamic computed property access such as `object[key]` is rejected by the bounded loader. For array iteration and selection, use supported methods such as `map` and `at(index)`; literal field/index access is supported.
|
|
40
|
+
|
|
41
|
+
`inputSchema` is an explicit object schema. Input precedence: optional schema defaults, script defaults, input file, then explicit `--set path=value`. Objects merge by field; arrays replace completely. Unknown keys, overlapping `--set` paths, schema errors and missing fields stop preparation. Use decimal strings for uint256; JavaScript numbers cannot represent large integers. JSON files support typed tuples, object arrays, nested arrays, bytes, zero and false. Derived values belong in pure helpers or `planOperations`; input fields marked `x-derived` cannot be set. Existing task producers still use synchronous `produce(inputs)` and `x-policy: computed` provenance, checked again by the shared input reader.
|
|
42
|
+
|
|
43
|
+
Per-network values stay in `parameters.yaml` (`defaults` plus `params.<network>`). Development reads and computed outputs are not automatically copied to production: scripts evaluate against each selected target during qualification. Complete production inputs before freezing.
|
|
44
|
+
|
|
45
|
+
## Controlled reads and ordered steps
|
|
46
|
+
|
|
47
|
+
Declare `reads.chain: true` for a step that calls `await p.readContract({address,abi:['function value() view returns (uint256)'],method:'value()',args:[],caller?})`. Only view/pure ABI functions are accepted. The port returns ABI-normalized data (integers remain decimal strings); evidence includes chain, pinned source block, simulated query block/hash, caller, target, ABI, method, arguments, return types and actual value. Use a pure `produce(inputs)` helper to turn these values into arrays/objects and return native operations. The emitted operations and every query are frozen into custom evidence.
|
|
48
|
+
|
|
49
|
+
File ports are task-root-relative and require `reads.files`. `resolve` requires declared `reads.params`, `reads.state` or public `reads.target`. Native `view` writes normalized results under `$state.<saveAs-or-operationId>.value` (single result) and `.values` (ordered results). Console strings are not parameter sources.
|
|
50
|
+
|
|
51
|
+
Every mutating operation must provide a readable `name` and `description` before approval, including its business intent. Steps have stable `id` and optional `dependsOn`. Dependencies must precede the step in declaration order. Repeated `--step` flags select whole business steps in declaration order. Omitted dependencies require explicit `satisfiedBy[dependencyId]` read queries with an expected result; they are checked on the actual selected network before planning the dependent step. Missing dependencies fail; unselected steps are never automatically run. Proxy/CREATE2 internal transaction groups remain indivisible. Results that genuinely require an earlier real transaction require a separately confirmed next deployment round.
|
|
52
|
+
|
|
53
|
+
Chain reads during preparation do not imply state invariants at execution. If the business needs unchanged input state, include explicit preconditions or an atomic contract guard; a separate chain read cannot guarantee atomic execution.
|
|
54
|
+
|
|
55
|
+
## Terminal host
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
npx --no-install gate-tool delivery run scripts/operations/configure.ts \
|
|
59
|
+
--network sepoliaDev --params inputs/configure.json --set value=200
|
|
60
|
+
npx --no-install gate-tool delivery run scripts/operations/system.ts \
|
|
61
|
+
--network sepoliaDev --step configure-vault --params inputs/system.json --execute
|
|
62
|
+
npx --no-install gate-tool delivery run --resume <executionId> --execute
|
|
63
|
+
npx --no-install gate-tool delivery run --reprepare <unsignedExecutionId> --set value=201
|
|
64
|
+
npx --no-install gate-tool delivery release --deployment <deploymentId>
|
|
65
|
+
npx --no-install gate-tool delivery run --release scripts/tasks/<deploymentId>/releases/<releaseId>/release.json \
|
|
66
|
+
--network ethProd --export-calldata
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Default run only prepares/simulates; it returns deploymentId, executionId and the ordered transactions. Use `--signer <public-address>` for keyless preparation, or provide `PRIVATE_KEY` in the environment/project `.env`. No secret is accepted as a command argument. Execution prints the exact unsigned transaction and requires `approve <signingRequestId>` in the terminal. Noninteractive runs without a genuine response retain preparation and stop. No `--yes` authorization bypass exists. An export does not require a key or gas.
|
|
70
|
+
|
|
71
|
+
The terminal host loads public RPC configuration from `rpc.env` and the process environment for keyless preparation, release/export and observation without `--execute`; it does not open `.env`. Keep public RPC values in `rpc.env`. The credential file is loaded by this host only for explicit execution or a new run that needs to resolve its signer from credentials. Simulation workers still load the canonical Hardhat configuration; its optional credential-file fallback and the static RPC observer both permit a protected `.env` to remain unreadable.
|
|
72
|
+
|
|
73
|
+
`--resume` forbids new script, network, parameter and step options. Signed bytes and nonce reservations are durable before broadcast. Reconcile original hashes; never rerun a successful transaction as recovery. `--hashes <json>` supplies explicit transactionId-to-original-hash arrays for external reconciliation. RPC, finality and uncertain-signature failures retain the original execution identity.
|
|
74
|
+
|
|
75
|
+
For an unsigned, unfrozen native preparation, `--reprepare` retains deploymentId, revokes the original execution and approval, reserves one replacement executionId, merges new inputs and simulates again. Invalid input is rejected before revocation. Explicit production overrides are retained. Once signing has started, use resume or a new round. App offers the same invalidation through its owning deployment record after cancellation; it rechecks the confirmed scope and never uses native metadata to replace a managed requirement.
|
|
76
|
+
|
|
77
|
+
The host store is private local data, outside the project, under `~/.gate-tool/delivery`. It holds signature intents/results and the shared ExecutionStore protocol. Never put it in Git or public handoff files. App/CLI transitions require the original plan/context and signing recovery records; missing state is a recovery gap, never permission to allocate a parallel execution.
|
|
78
|
+
|
|
79
|
+
## Production
|
|
80
|
+
|
|
81
|
+
Declare production aliases in Hardhat/config.yaml and choose them with repeated `--release-network`. Dev acceptance requires actual finalized transactions, business assertions and CheckCode; a read-only script returns query results without pretending to be deployment acceptance. After acceptance, complete production values in the same task (network overrides where needed), configure each production `admin` public address, and commit all modified contract sources. Script commits are not required; their bytes are captured.
|
|
82
|
+
|
|
83
|
+
`delivery release` verifies actual historical dev acceptance and committed contract identity, qualifies every selected production network on an isolated fork, then asks for `release <candidateHash>` before marker-last freezing. It never broadcasts. Administrators consume the existing release without entering business parameters. Release execution forbids script, params, set and step overrides. Production preparation must preserve released ABI/calldata intent. Execute only with the configured authorized signer, otherwise explicitly export for the external executor.
|
|
84
|
+
|
|
85
|
+
The public artifact remains a single `scripts/tasks/<deploymentId>/deliveries/<digest>/calldata.json` array, only when requested for external execution. Every call carries its intended executor, chain(s), target, ABI, description/parameter intent and encoded data; CREATE2/multicall payload reviews reuse the existing projection. Export is artifact delivery, not acceptance. External execution is reconciled and state/bytecode verified afterward.
|
package/package.json
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gate-evm-tools",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"description": "Gate 智能合约工具集 - 字节码检查、合约升级验证、合约状态同步",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
7
|
+
"./deployment-zksync": {
|
|
8
|
+
"types": "./dist/deployment-zksync/index.d.ts",
|
|
9
|
+
"import": "./dist/deployment-zksync/index.js",
|
|
10
|
+
"require": "./dist-cjs/deployment-zksync/index.js"
|
|
11
|
+
},
|
|
12
|
+
"./migration": {
|
|
13
|
+
"types": "./dist/migration/index.d.ts",
|
|
14
|
+
"import": "./dist/migration/index.js",
|
|
15
|
+
"require": "./dist-cjs/migration/index.js"
|
|
16
|
+
},
|
|
7
17
|
"./custody": {
|
|
8
18
|
"types": "./dist/custody/index.d.ts",
|
|
9
19
|
"import": "./dist/custody/index.js",
|
|
@@ -114,10 +124,28 @@
|
|
|
114
124
|
"types": "./dist/deployment-evm/index.d.ts",
|
|
115
125
|
"import": "./dist/deployment-evm/index.js",
|
|
116
126
|
"require": "./dist-cjs/deployment-evm/index.js"
|
|
127
|
+
},
|
|
128
|
+
"./delivery-scripts": {
|
|
129
|
+
"types": "./dist-runtime/delivery/scripts.d.ts",
|
|
130
|
+
"default": "./dist-runtime/delivery/scripts.js"
|
|
131
|
+
},
|
|
132
|
+
"./delivery-cli-host": {
|
|
133
|
+
"types": "./dist-runtime/delivery/cli-host.d.ts",
|
|
134
|
+
"default": "./dist-runtime/delivery/cli-host.js"
|
|
135
|
+
},
|
|
136
|
+
"./delivery-execution-records": {
|
|
137
|
+
"types": "./dist-runtime/delivery/execution-records.d.ts",
|
|
138
|
+
"default": "./dist-runtime/delivery/execution-records.js"
|
|
117
139
|
}
|
|
118
140
|
},
|
|
119
141
|
"typesVersions": {
|
|
120
142
|
"*": {
|
|
143
|
+
"deployment-zksync": [
|
|
144
|
+
"dist/deployment-zksync/index.d.ts"
|
|
145
|
+
],
|
|
146
|
+
"migration": [
|
|
147
|
+
"dist/migration/index.d.ts"
|
|
148
|
+
],
|
|
121
149
|
"custody": [
|
|
122
150
|
"dist/custody/index.d.ts"
|
|
123
151
|
],
|
|
@@ -189,6 +217,15 @@
|
|
|
189
217
|
],
|
|
190
218
|
"deployment-evm": [
|
|
191
219
|
"dist/deployment-evm/index.d.ts"
|
|
220
|
+
],
|
|
221
|
+
"delivery-scripts": [
|
|
222
|
+
"dist-runtime/delivery/scripts.d.ts"
|
|
223
|
+
],
|
|
224
|
+
"delivery-cli-host": [
|
|
225
|
+
"dist-runtime/delivery/cli-host.d.ts"
|
|
226
|
+
],
|
|
227
|
+
"delivery-execution-records": [
|
|
228
|
+
"dist-runtime/delivery/execution-records.d.ts"
|
|
192
229
|
]
|
|
193
230
|
}
|
|
194
231
|
},
|
|
@@ -230,6 +267,8 @@
|
|
|
230
267
|
"author": "",
|
|
231
268
|
"license": "MIT",
|
|
232
269
|
"dependencies": {
|
|
270
|
+
"@openzeppelin/upgrades-core": "1.44.2",
|
|
271
|
+
"ethers": "6.15.0",
|
|
233
272
|
"ajv": "8.17.1",
|
|
234
273
|
"chalk": "^5.3.0",
|
|
235
274
|
"commander": "^11.1.0",
|
|
@@ -248,37 +287,21 @@
|
|
|
248
287
|
"@matterlabs/hardhat-zksync-upgradable": "1.10.0",
|
|
249
288
|
"@nomicfoundation/hardhat-ethers": "3.1.2",
|
|
250
289
|
"@openzeppelin/hardhat-upgrades": "^3.9.1",
|
|
251
|
-
"@openzeppelin/upgrades-core": "^1.44.2",
|
|
252
290
|
"@types/fs-extra": "^11.0.4",
|
|
253
291
|
"@types/node": "^24.7.2",
|
|
254
292
|
"@types/prompts": "^2.4.9",
|
|
255
293
|
"@types/semver": "^7.8.0",
|
|
256
|
-
"ethers": "^6.15.0",
|
|
257
294
|
"ethers5": "npm:ethers@5.7.2",
|
|
258
295
|
"hardhat": "2.27.1",
|
|
259
296
|
"ts-node": "10.9.2"
|
|
260
297
|
},
|
|
261
298
|
"peerDependencies": {
|
|
262
|
-
"@
|
|
263
|
-
"@matterlabs/hardhat-zksync-ethers": "1.4.0",
|
|
264
|
-
"@matterlabs/hardhat-zksync-solc": "1.5.1",
|
|
265
|
-
"@matterlabs/hardhat-zksync-upgradable": "1.10.0",
|
|
266
|
-
"@openzeppelin/hardhat-upgrades": ">=2.0.0 <4.0.0",
|
|
267
|
-
"@openzeppelin/upgrades-core": ">=1.0.0 <2.0.0",
|
|
299
|
+
"@openzeppelin/hardhat-upgrades": ">=1.0.0 <4.0.0",
|
|
268
300
|
"ethers": ">=5.7.0 <7.0.0",
|
|
269
301
|
"hardhat": ">=2.0.0 <3.0.0"
|
|
270
302
|
},
|
|
271
303
|
"peerDependenciesMeta": {
|
|
272
|
-
"@
|
|
273
|
-
"optional": true
|
|
274
|
-
},
|
|
275
|
-
"@matterlabs/hardhat-zksync-ethers": {
|
|
276
|
-
"optional": true
|
|
277
|
-
},
|
|
278
|
-
"@matterlabs/hardhat-zksync-solc": {
|
|
279
|
-
"optional": true
|
|
280
|
-
},
|
|
281
|
-
"@matterlabs/hardhat-zksync-upgradable": {
|
|
304
|
+
"@openzeppelin/hardhat-upgrades": {
|
|
282
305
|
"optional": true
|
|
283
306
|
}
|
|
284
307
|
},
|
|
@@ -33,6 +33,7 @@ export const workerFailures: Readonly<Record<string, string>> = Object.freeze({
|
|
|
33
33
|
...sourceRpcFailures,
|
|
34
34
|
...Object.fromEntries(invariantMessages.map((message, index) => ['invariant-'+index,message])),
|
|
35
35
|
'compiler-input-drift': 'Compiler input bytes changed during qualification.',
|
|
36
|
+
'script-dependency-unmet': 'Selected business step has an unmet live dependency; check its satisfiedBy query against the selected network.',
|
|
36
37
|
});
|
|
37
38
|
|
|
38
39
|
/** Only exact reviewed messages or a fixed category may cross the worker channel. */
|
|
@@ -43,6 +44,7 @@ export function workerFailureReason(error: unknown): string | undefined {
|
|
|
43
44
|
const index = invariantMessages.findIndex(known => known === message);
|
|
44
45
|
if (index >= 0) return 'invariant-'+index;
|
|
45
46
|
if (message.startsWith('Compiler input drift: ')) return 'compiler-input-drift';
|
|
47
|
+
if (message.startsWith('Unmet live dependency ')) return 'script-dependency-unmet';
|
|
46
48
|
return undefined;
|
|
47
49
|
}
|
|
48
50
|
|
|
@@ -6,15 +6,16 @@ export function openAggregateSources(input:{workspaceRoot:string;projectRoot:str
|
|
|
6
6
|
const read=()=>{
|
|
7
7
|
const sources=input.requests.map(request=>readOwnedDeliverySource({workspaceRoot:input.workspaceRoot,projectRoot:input.projectRoot,request}));
|
|
8
8
|
const groups=new Map<string,typeof sources>();
|
|
9
|
-
for(const source of sources){const key=source.
|
|
9
|
+
for(const source of sources){const key=source.kind+'\0'+source.request.sourceRef.path;const group=groups.get(key)??[];group.push(source);groups.set(key,group);}
|
|
10
10
|
const definitions=[];const tasks=new Map<string,unknown>(),lanes=new Map<string,unknown>();
|
|
11
11
|
let identity:string|undefined;
|
|
12
12
|
for(const group of groups.values()){
|
|
13
13
|
const first=group[0];
|
|
14
|
+
if(first.kind==='standalone'){definitions.push({path:first.request.sourceRef.path,definition:first.sourceDefinition});continue;}
|
|
14
15
|
const projection=readDeliverySource({workspaceRoot:input.workspaceRoot,projectRoot:input.projectRoot,request:first.request,
|
|
15
|
-
sourceRoots:group.map(source=>source.invocation
|
|
16
|
+
sourceRoots:group.map(source=>source.invocation!.task.planKey)});
|
|
16
17
|
if(group.some(source=>source.observation.sha256!==projection.observation.sha256))throw new Error('Handoff changed during multi-root source capture');
|
|
17
|
-
const definition=projection.sourceDefinition;
|
|
18
|
+
const definition=projection.sourceDefinition as import('./source').DefinitionSnapshot;
|
|
18
19
|
const currentIdentity=canonicalJson([definition.contract,definition.schema,definition.taskId,definition.flow??null]);
|
|
19
20
|
if(identity!==undefined&&identity!==currentIdentity)throw new Error('Conflicting aggregate handoff identity');
|
|
20
21
|
identity=currentIdentity;
|
|
@@ -23,7 +24,7 @@ export function openAggregateSources(input:{workspaceRoot:string;projectRoot:str
|
|
|
23
24
|
lanes.set(key,lane);
|
|
24
25
|
}
|
|
25
26
|
// Detect conflicting duplicates across documents without sorting/reconstructing any codec task list.
|
|
26
|
-
for(const task of
|
|
27
|
+
for(const task of definition.tasks){const key=first.request.sourceRef.taskId+'\0'+task.planKey;
|
|
27
28
|
if(tasks.has(key)&&canonicalJson(tasks.get(key))!==canonicalJson(task))throw new Error('Conflicting aggregate source definition');tasks.set(key,task);
|
|
28
29
|
}
|
|
29
30
|
definitions.push({path:first.request.sourceRef.path,definition:projection.sourceDefinition});
|
|
@@ -34,6 +35,6 @@ export function openAggregateSources(input:{workspaceRoot:string;projectRoot:str
|
|
|
34
35
|
return Object.freeze({...initial,sourceDefinitionHash:semanticHash(initial.definitions),assertUnchanged(){
|
|
35
36
|
const current=read();
|
|
36
37
|
if(canonicalJson(current.definitions)!==canonicalJson(initial.definitions))throw new Error('Aggregate source definition drift');
|
|
37
|
-
for(let i=0;i<current.sources.length;i++)if(canonicalJson(current.sources[i].
|
|
38
|
+
for(let i=0;i<current.sources.length;i++)if(canonicalJson(current.sources[i].scope)!==canonicalJson(initial.sources[i].scope))throw new Error('Aggregate invocation drift');
|
|
38
39
|
}});
|
|
39
40
|
}
|
|
@@ -77,11 +77,11 @@ async function dispatch(message:WorkerMessage):Promise<unknown>{
|
|
|
77
77
|
return {chainId:BigInt(chain).toString(),blockNumber:Number(BigInt(block.number)),blockHash:block.hash};
|
|
78
78
|
}};
|
|
79
79
|
phase='planning';stage=await stageDeliveryPlan({context,header,identities,steps:initial.steps,derivationSeed:initial.derivationSeed??initial.executionId});
|
|
80
|
-
if(!stage.snapshot.preparations.length){
|
|
80
|
+
if(!stage.snapshot.preparations.length && stage.payload.transactions.length){
|
|
81
81
|
phase='existing-code-artifacts';
|
|
82
|
-
const {collectExistingCodeArtifacts,requiredExistingAddresses}=require('./existing-code') as typeof import('./existing-code');
|
|
82
|
+
const {collectExistingCodeArtifacts,requiredExistingAddresses,interactionCoverageRegistry}=require('./existing-code') as typeof import('./existing-code');
|
|
83
83
|
const {fileBytes}=require('./materialization') as typeof import('./materialization');
|
|
84
|
-
await collectExistingCodeArtifacts({target:request.network,addresses:requiredExistingAddresses({plan:stage.payload,verification:stage.snapshot.verification}),registry:JSON.parse(fileBytes(root,'contractInfo.json')??'{}'),metadata:JSON.parse(fileBytes(root,'deploymentInfo.json')??'{"version":1,"networks":{}}'),readArtifact:name=>hre.artifacts.readArtifact(name)});
|
|
84
|
+
await collectExistingCodeArtifacts({target:request.network,addresses:requiredExistingAddresses({plan:stage.payload,verification:stage.snapshot.verification}),registry:interactionCoverageRegistry({plan:stage.payload as any,verification:stage.snapshot.verification},JSON.parse(fileBytes(root,'contractInfo.json')??'{}'),request.network),metadata:JSON.parse(fileBytes(root,'deploymentInfo.json')??'{"version":1,"networks":{}}'),readArtifact:name=>hre.artifacts.readArtifact(name)});
|
|
85
85
|
}
|
|
86
86
|
phase='staged-reread';stagedCompiler=compiler.evidence();config!.assertUnchanged();
|
|
87
87
|
contribution={compiler:stagedCompiler,custom:stage.payload.customInputClosure,payloadHash:semanticHash(stage.payload),invariantHash:stage.invariantHash,snapshot:stage.snapshot};
|
|
@@ -35,7 +35,7 @@ function same(a:unknown,b:unknown,label:string):void{if(canonicalJson(a)!==canon
|
|
|
35
35
|
class DiscoveryReplayError extends Error {}
|
|
36
36
|
export async function collectDeliveryAggregate(raw:DeliveryAggregateOptions):Promise<Readonly<DeliveryAggregate>> {
|
|
37
37
|
try{return await collectOwnedAggregate(raw);}
|
|
38
|
-
catch(error){if(error instanceof OwnedWorkerFailure||error instanceof DiscoveryReplayError)throw error;throw new Error('Delivery aggregate input qualification failed');}
|
|
38
|
+
catch(error){if(error instanceof OwnedWorkerFailure||error instanceof DiscoveryReplayError)throw error;throw new Error('Delivery aggregate input qualification failed',{cause:error});}
|
|
39
39
|
}
|
|
40
40
|
async function collectOwnedAggregate(raw:DeliveryAggregateOptions):Promise<Readonly<DeliveryAggregate>> {
|
|
41
41
|
const input=strictData(raw);
|
|
@@ -54,7 +54,7 @@ async function collectOwnedAggregate(raw:DeliveryAggregateOptions):Promise<Reado
|
|
|
54
54
|
// Every invocation gets its own actual environment/network/step/sourceRef validation.
|
|
55
55
|
const sourceOwner=openAggregateSources({workspaceRoot:workspace,projectRoot:input.projectRoot,requests:targets.map(x=>x.request)});
|
|
56
56
|
const {sources,definitions:sourceDefinitions,sourceDefinitionHash}=sourceOwner;
|
|
57
|
-
for(const source of sources){const scope=source.
|
|
57
|
+
for(const source of sources){const scope=source.scope as any,first=sources[0].scope as any;
|
|
58
58
|
for(const key of ['deploymentId','developmentNetwork','releaseTargetNetworks','projectRoot'])same(scope[key],first[key],'Aggregate business scope');
|
|
59
59
|
}
|
|
60
60
|
let runtime:RuntimeObservation|undefined,business:ReturnType<typeof openDeliveryInputs>|undefined;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/** Terminal host for the existing durable EOA kernel. Never used as business script ports. */
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import readline from 'node:readline';
|
|
6
|
+
import { createRequire } from 'node:module';
|
|
7
|
+
import { semanticHash, canonicalJson } from '../workflow/lib/canonicalData';
|
|
8
|
+
import { openExecutionStore } from './execution-store';
|
|
9
|
+
import type { EoaApprovalSnapshot, EoaSignOnlySigner } from './eoa';
|
|
10
|
+
import type { DeliveryPlan } from './plan';
|
|
11
|
+
import type { UnsignedEnvelope } from './execution-model';
|
|
12
|
+
import { atomicDevelopmentWrite } from './materialization';
|
|
13
|
+
import { writeImmutableDeliveryFile } from './development-inputs';
|
|
14
|
+
import { parseConfigurationDefinition } from './configuration-definition';
|
|
15
|
+
import { productionChildEnvironment } from './production-environment';
|
|
16
|
+
import { readInputBytes } from './input-files';
|
|
17
|
+
export function sharedDeliveryHostRoot(){return path.join(os.homedir(),'.gate-tool','delivery');}
|
|
18
|
+
export function terminalApproval(){
|
|
19
|
+
let input:readline.Interface|undefined;const queue:string[]=[];const pending:Array<(s:string)=>void>=[];let ended=false;
|
|
20
|
+
const start=()=>{if(input)return;input=readline.createInterface({input:process.stdin,crlfDelay:Infinity,terminal:false});input.on('line',line=>{const next=pending.shift();if(next)next(line);else queue.push(line);});input.on('close',()=>{ended=true;for(const next of pending.splice(0))next('');});};
|
|
21
|
+
return {async confirm(message:string,phrase:string){start();process.stdout.write(`${message}\nType ${phrase}\n`);const answer=queue.length?queue.shift()!:ended?'':await new Promise<string>(resolve=>pending.push(resolve));if(answer!==phrase)throw Error('Terminal approval declined or unavailable; preparation retained for resume');},
|
|
22
|
+
async withApproval<T>(s:EoaApprovalSnapshot,work:()=>Promise<T>){await this.confirm(`Transaction approval ${canonicalJson({executionId:s.context.executionId,planHash:s.context.planHash,transaction:s.transaction,unsigned:s.unsigned})}`,`approve ${s.signingRequestId}`);return work();},close(){input?.close();}};
|
|
23
|
+
}
|
|
24
|
+
export function loadProjectEnvironment(root:string,credentials=true){for(const name of credentials?['rpc.env','.env']:['rpc.env']){const file=path.join(root,name);if(fs.existsSync(file))process.loadEnvFile(file);}}
|
|
25
|
+
export function projectRpc(root:string,network:string){
|
|
26
|
+
const config=parseConfigurationDefinition(readInputBytes(root,'hardhat.config.ts'),network,productionChildEnvironment(process.env)).userConfig.networks[network];
|
|
27
|
+
const url=new URL(config.url);if(!['http:','https:'].includes(url.protocol))throw Error('HTTP RPC required');
|
|
28
|
+
return {url:config.url,async request(method:string,params:readonly unknown[]):Promise<any>{
|
|
29
|
+
const r=await fetch(url,{method:'POST',headers:{'content-type':'application/json',...config.httpHeaders},body:JSON.stringify({jsonrpc:'2.0',id:1,method,params}),signal:AbortSignal.timeout(30000)});
|
|
30
|
+
if(!r.ok)throw Error(`RPC HTTP ${r.status}`);const body=await r.text();if(Buffer.byteLength(body)>16*1024*1024)throw Error('RPC response exceeds limit');const v=JSON.parse(body);if(v.error||!Object.hasOwn(v,'result'))throw Error(`RPC ${method} failed${v.error?.message?': '+v.error.message:''}`);return v.result;
|
|
31
|
+
}};
|
|
32
|
+
}
|
|
33
|
+
export async function createTerminalSigner(root:string,network:string,hostRoot=sharedDeliveryHostRoot()):Promise<EoaSignOnlySigner|undefined>{
|
|
34
|
+
const credential=process.env.PRIVATE_KEY;if(!credential)return undefined;
|
|
35
|
+
const req=createRequire(path.join(root,'package.json')),ethers=req('ethers'),rpc=projectRpc(root,network);
|
|
36
|
+
const signer=require('../../dist-cjs/custody/signer.js').createSigner({ethers,credential,provider:new ethers.JsonRpcProvider(rpc.url)});
|
|
37
|
+
const address=(await signer.getAddress()).toLowerCase(),dir=path.join(hostRoot,'signatures');fs.mkdirSync(dir,{recursive:true,mode:0o700});
|
|
38
|
+
const read=(id:string)=>{const file=path.join(dir,`${id}.json`);if(!fs.existsSync(file))return undefined;const st=fs.lstatSync(file);if(!st.isFile()||st.isSymbolicLink()||(st.mode&0o777)!==0o600)throw Error('Unsafe signature record');return JSON.parse(fs.readFileSync(file,'utf8'));};
|
|
39
|
+
const save=(file:string,data:unknown)=>writeImmutableDeliveryFile(hostRoot,`signatures/${file}`,Buffer.from(canonicalJson(data)+'\n'));
|
|
40
|
+
return {address,async sign(id,unsigned){if(!/^[a-f0-9]{64}$/.test(id))throw Error('Invalid signing request');const old=read(id);if(old){if(old.id!==id||old.identity!==semanticHash(unsigned))throw Error('Signature request conflict');if(old.state!=='signed')throw Error('Original signing result unavailable; recover original result without re-signing');return old.raw;}
|
|
41
|
+
save(`${id}.json`,{version:1,id,identity:semanticHash(unsigned),state:'intent'});
|
|
42
|
+
const {signer:_signer,operation:_operation,...rest}=unsigned;
|
|
43
|
+
const tx:any={...rest,nonce:Number(unsigned.nonce)};delete tx.gasPrice;delete tx.maxFeePerGas;delete tx.maxPriorityFeePerGas;
|
|
44
|
+
if(unsigned.type===2){tx.maxFeePerGas=unsigned.maxFeePerGas;tx.maxPriorityFeePerGas=unsigned.maxPriorityFeePerGas;}else tx.gasPrice=unsigned.gasPrice;
|
|
45
|
+
if(unsigned.type===0)delete tx.accessList;
|
|
46
|
+
const raw=await signer.signTransaction(tx);require('./eoa-signed').verifyEoaSigned(raw,unsigned);atomicDevelopmentWrite(hostRoot,`signatures/${id}.json`,canonicalJson({version:1,id,identity:semanticHash(unsigned),state:'signed',raw})+'\n');return raw;
|
|
47
|
+
},async recover(id){const prior=read(id);return prior?.state==='signed'?prior.raw:undefined;}};
|
|
48
|
+
}
|
|
49
|
+
export async function terminalUnsigned(plan:DeliveryPlan,store:Awaited<ReturnType<typeof openExecutionStore>>,rpc:ReturnType<typeof projectRpc>):Promise<UnsignedEnvelope|undefined>{
|
|
50
|
+
const state=await store.readExecution(plan.executionId),index=state?.completedCount??0,tx=plan.transactions[index];if(!tx)return undefined;
|
|
51
|
+
const prior=state?.transactions[index];if(prior?.unsigned)return prior.unsigned;
|
|
52
|
+
if(tx.route!=='operator')return undefined;
|
|
53
|
+
const gas=BigInt(await rpc.request('eth_estimateGas',[{from:tx.executor,to:tx.to,data:tx.data,value:'0x'+BigInt(tx.value).toString(16)}]));
|
|
54
|
+
return {chainId:plan.chainId,signer:tx.executor,nonce:BigInt(await rpc.request('eth_getTransactionCount',[tx.executor,'pending'])).toString(),to:tx.to,value:tx.value,data:tx.data,operation:0,type:0,gasLimit:((gas*120n+99n)/100n).toString(),gasPrice:BigInt(await rpc.request('eth_gasPrice',[])).toString(),maxFeePerGas:null,maxPriorityFeePerGas:null,accessList:[]};
|
|
55
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/** Official standalone CLI orchestration over the common delivery core and EOA store. */
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { randomUUID } from 'node:crypto';
|
|
5
|
+
import { createRequire } from 'node:module';
|
|
6
|
+
import YAML from 'yaml';
|
|
7
|
+
import {setupDeliveryProject} from './setup';
|
|
8
|
+
import { prepareStandaloneTask,reprepareStandaloneTask } from './scripts';
|
|
9
|
+
import {claimProductionExecution,saveExecutionRecord,executionRecordPath} from './execution-records';
|
|
10
|
+
import { readStandaloneTask } from './standalone-source';
|
|
11
|
+
import { collectDeliveryAggregate, type DeliveryAggregateOptions } from './aggregate';
|
|
12
|
+
import { persistDevelopmentInputs, writeImmutableDeliveryFile } from './development-inputs';
|
|
13
|
+
import type { ProductionOptions } from './production';
|
|
14
|
+
import { openExecutionStore } from './execution-store';
|
|
15
|
+
import { loadDeliveryPublicTarget } from './config';
|
|
16
|
+
import { safeId, type DeliveryRequest } from './protocol';
|
|
17
|
+
import { readInputBytes } from './input-files';
|
|
18
|
+
import { canonicalJson, semanticHash } from '../workflow/lib/canonicalData';
|
|
19
|
+
import { terminalApproval, createTerminalSigner, sharedDeliveryHostRoot, projectRpc, terminalUnsigned, loadProjectEnvironment } from './cli-host';
|
|
20
|
+
const json=(root:string,file:string)=>JSON.parse(readInputBytes(root,file).toString());
|
|
21
|
+
const save=(root:string,file:string,v:unknown)=>writeImmutableDeliveryFile(root,file,Buffer.from(canonicalJson(v)+'\n'));
|
|
22
|
+
const descriptor=executionRecordPath;
|
|
23
|
+
export const scriptCliHelp=`gate-tool delivery run <script.ts> --network <alias> [--params <json|yaml>] [--set path=value] [--step <id>] [--signer <address>] [--release-network <alias>] [--execute]
|
|
24
|
+
gate-tool delivery run --resume <executionId> [--execute|--export-calldata] [--hashes <json>]
|
|
25
|
+
gate-tool delivery release --deployment <deploymentId>
|
|
26
|
+
gate-tool delivery run --release <release.json> --network <prodAlias> [--execute|--export-calldata] [--hashes <json>]
|
|
27
|
+
gate-tool delivery run --reprepare <unsignedExecutionId> [--params <file>] [--set path=value] [--step <id>] [--execute]\nDefault: prepare/simulate, no broadcast. Execution asks for exact transaction approval in the terminal. Secrets: PRIVATE_KEY environment only. See node_modules/gate-evm-tools/docs/script-execution.md.`;
|
|
28
|
+
function argumentsFor(args:string[]){
|
|
29
|
+
const options:Record<string,string[]>={};const positional:string[]=[];const flags=new Set(['execute','export-calldata']);const allowed=new Set(['network','params','set','step','signer','release-network','resume','release','deployment','hashes','description','reference-deployment','reprepare']);
|
|
30
|
+
for(let i=0;i<args.length;i++){const arg=args[i];if(!arg.startsWith('--')){positional.push(arg);continue;}const k=arg.slice(2);if(flags.has(k)){if(options[k])throw Error(`Duplicate --${k}`);options[k]=['true'];continue;}if(!allowed.has(k)||!args[i+1]||args[i+1].startsWith('--'))throw Error(`Unknown or missing option ${arg}`);if(options[k]&&!['set','step','release-network'].includes(k))throw Error(`Duplicate --${k}`);(options[k]??=[]).push(args[++i]);}
|
|
31
|
+
if(options.execute&&options['export-calldata'])throw Error('--execute and --export-calldata are mutually exclusive');return {o:options,p:positional};
|
|
32
|
+
}
|
|
33
|
+
export async function runStandaloneCli(args:string[]){
|
|
34
|
+
const root=fs.realpathSync(process.cwd());const {o,p}=argumentsFor(args.slice(1)),cmd=args[0],approval=terminalApproval();
|
|
35
|
+
const one=(k:string)=>o[k]?.[0];const hashes=one('hashes')?json(root,one('hashes')!):{};
|
|
36
|
+
loadProjectEnvironment(root,!!o.execute||(cmd==='run'&&!one('resume')&&!one('release')&&!one('reprepare')&&!one('signer')));
|
|
37
|
+
try{
|
|
38
|
+
if(cmd==='release'){
|
|
39
|
+
const {prepareDeliveryRelease,finalizeDeliveryRelease,captureDevelopmentReleaseHistory}=require('./release') as typeof import('./release');
|
|
40
|
+
if(p.length||Object.keys(o).some(k=>k!=='deployment')||!one('deployment'))throw Error('release requires only --deployment');
|
|
41
|
+
const id=safeId(one('deployment'),'deploymentId'),taskPath=`scripts/tasks/${id}/task.yaml`,task=readStandaloneTask(root,taskPath);
|
|
42
|
+
const records=fs.readdirSync(path.join(root,'.gate-delivery/executions')).filter(f=>f.endsWith('.json')).map(f=>json(root,`.gate-delivery/executions/${f}`));
|
|
43
|
+
const dev=records.filter(r=>r.kind==='development'&&r.deploymentId===id&&!fs.existsSync(path.join(root,`.gate-delivery/development/${r.executionId}.superseded.json`)));if(dev.length!==1)throw Error('Exactly one original development preparation required');
|
|
44
|
+
const releaseId=`${id}-release-${dev[0].executionId.slice(0,8)}`;
|
|
45
|
+
const aggregate=json(root,dev[0].aggregatePath),history=captureDevelopmentReleaseHistory({root,source:dev[0].source,aggregate});
|
|
46
|
+
const scope={workspaceRoot:root,projectRoot:'.',handoff:taskPath,taskId:id,deploymentId:id};
|
|
47
|
+
const candidateFile=`.gate-delivery/releases/${releaseId}/candidate.json`;
|
|
48
|
+
if(!fs.existsSync(path.join(root,candidateFile))){const targets=[];for(const network of task.releaseTargetNetworks){const target=loadDeliveryPublicTarget(root,network,'prod'),operator=target.admin;if(!operator||!/^0x[\da-f]{40}$/i.test(operator))throw Error(`Explicit prod admin/operator address required in config.yaml for ${network}`);const rpc=projectRpc(root,network),block=await rpc.request('eth_getBlockByNumber',['latest',false]);targets.push({executionId:randomUUID(),request:{version:2 as const,environment:'prod' as const,purpose:'prod-qualification' as const,mode:'simulate' as const,network,operator,fork:{blockNumber:Number(BigInt(block.number)),blockHash:block.hash,readOnly:true as const},sourceRef:{kind:'standalone' as const,path:taskPath,deploymentId:id}}});}
|
|
49
|
+
await prepareDeliveryRelease({...scope,releaseId,targets,development:history});
|
|
50
|
+
}
|
|
51
|
+
const candidate=json(root,candidateFile);await approval.confirm(`Freeze production release ${releaseId}\nTargets: ${task.releaseTargetNetworks.join(', ')}\nInputs: ${candidate.aggregate.inputsHash}`,`release ${candidate.candidateHash}`);
|
|
52
|
+
const result=await finalizeDeliveryRelease({...scope,releaseId});return {status:result.status,releaseFile:candidate.releaseRef.path,inputsHash:candidate.aggregate.inputsHash};
|
|
53
|
+
}
|
|
54
|
+
if(cmd!=='run')throw Error(scriptCliHelp);
|
|
55
|
+
let record:any;
|
|
56
|
+
if(one('reprepare')){
|
|
57
|
+
if(p.length||Object.keys(o).some(k=>!['reprepare','params','set','step','execute'].includes(k)))throw Error('reprepare accepts only original execution, params/set/step and execute');
|
|
58
|
+
const original=json(root,`.gate-delivery/development/${safeId(one('reprepare'),'executionId')}.source.json`),network=original.targets[0].request.network;
|
|
59
|
+
const store=await openExecutionStore({trustedRoot:sharedDeliveryHostRoot()});
|
|
60
|
+
const task=await reprepareStandaloneTask({root,executionId:one('reprepare')!,store,paramsFile:one('params'),sets:o.set,steps:o.step});
|
|
61
|
+
const executionId=task.executionId,source={...original,targets:[{...original.targets[0],executionId}]};
|
|
62
|
+
const aggregate=await collectDeliveryAggregate(source),saved=persistDevelopmentInputs({root,source,aggregate});record={kind:'development',deploymentId:task.deploymentId,executionId,source,...saved};saveExecutionRecord(root,record);
|
|
63
|
+
}else if(one('resume')){
|
|
64
|
+
if(p.length||Object.keys(o).some(k=>!['resume','execute','export-calldata','hashes'].includes(k)))throw Error('resume forbids script, parameter, network and step overrides');const id=safeId(one('resume'),'executionId');
|
|
65
|
+
if(fs.existsSync(path.join(root,descriptor(id))))record=json(root,descriptor(id));else{
|
|
66
|
+
const sourcePath=`.gate-delivery/development/${id}.source.json`,aggregatePath=`.gate-delivery/development/${id}.aggregate.json`;
|
|
67
|
+
const source=json(root,sourcePath),aggregate=json(root,aggregatePath);if(source.targets?.[0]?.executionId!==id||aggregate.collections?.[0]?.plan.executionId!==id)throw Error('Original execution preparation missing or mismatched');
|
|
68
|
+
record={kind:'development',deploymentId:aggregate.collections[0].plan.deploymentId,executionId:id,source,sourcePath,aggregatePath};
|
|
69
|
+
}
|
|
70
|
+
}else if(one('release')){
|
|
71
|
+
const {prepareDeliveryProduction}=require('./production') as typeof import('./production');
|
|
72
|
+
if(p.length||Object.keys(o).some(k=>!['release','network','execute','export-calldata','hashes'].includes(k))||!one('network'))throw Error('Production consumes a release and forbids script/parameter/step overrides');
|
|
73
|
+
const marker=json(root,one('release')!),bundle=json(root,marker.bundle.path),id=bundle.qualification[0].plan.deploymentId,network=one('network')!,target=bundle.targets.find((t:any)=>t.id===network);if(!target)throw Error('Network outside release');
|
|
74
|
+
const candidate=json(root,bundle.candidate.path),scope=candidate.scope;
|
|
75
|
+
let planKey='standalone',rev=1;
|
|
76
|
+
if(bundle.prodTaskGraph.schema!=='gate-delivery-standalone-release'){
|
|
77
|
+
const tasks=bundle.prodTaskGraph.tasks.filter((t:any)=>t.scope?.deployment?.targetNetwork===network&&t.scope.deployment.allowedActions.includes('simulate')&&t.scope.deployment.purpose==='prod-execution');
|
|
78
|
+
if(tasks.length!==1)throw Error('Release needs exactly one production preparation scope for this target');planKey=tasks[0].planKey;rev=tasks[0].rev;
|
|
79
|
+
}
|
|
80
|
+
record=await claimProductionExecution(root,{workspaceRoot:root,...scope,releaseRef:marker.releaseRef,planKey,rev,target:network,operator:target.admin});
|
|
81
|
+
await prepareDeliveryProduction(record.options);
|
|
82
|
+
|
|
83
|
+
}else{
|
|
84
|
+
if(p.length!==1||!one('network')||one('hashes')||one('deployment')||o['export-calldata'])throw Error('Script run requires a script and --network; export is release/resume only');
|
|
85
|
+
const network=one('network')!,signer=one('signer')??(await createTerminalSigner(root,network))?.address;if(!signer)throw Error('Preparation needs --signer <public address> or PRIVATE_KEY');
|
|
86
|
+
const configured=YAML.parse(readInputBytes(root,'config.yaml').toString());
|
|
87
|
+
const targets=[network,...(o['release-network']??[])].map((name,i)=>{const v=configured[name];if(!v||v.environment!==(i?'prod':'dev'))throw Error(`Declare ${name} environment in config.yaml first`);return {network:name,environment:v.environment,finality:v.finality??{confirmations:1},openzeppelin:v.openzeppelin??{manifestDir:i?'.openzeppelin':'.openzeppelin.dev'}};});
|
|
88
|
+
const setup=setupDeliveryProject({workspaceRoot:root,projectRoot:'.',targets});if(setup.status!=='ready')throw Error('Project dependencies are pending; install the declared versions, then rerun');
|
|
89
|
+
const task=prepareStandaloneTask({root,script:p[0],network,paramsFile:one('params'),sets:o.set,steps:o.step,description:one('description'),releaseNetworks:o['release-network'],referenceDeploymentId:one('reference-deployment')});
|
|
90
|
+
const executionId=randomUUID(),source:DeliveryAggregateOptions={workspaceRoot:root,projectRoot:'.',selection:'development',targets:[{executionId,request:{version:2,environment:'dev',purpose:'dev-execution',mode:'simulate',network,devSigner:signer,sourceRef:{kind:'standalone',path:task.taskPath,deploymentId:task.deploymentId}}}]};
|
|
91
|
+
const aggregate=await collectDeliveryAggregate(source),saved=persistDevelopmentInputs({root,source,aggregate});record={kind:'development',deploymentId:task.deploymentId,executionId,source,...saved};saveExecutionRecord(root,record);
|
|
92
|
+
}
|
|
93
|
+
const executionId=record.executionId;
|
|
94
|
+
if(record.kind==='production'){
|
|
95
|
+
const {inspectDeliveryProduction,freezeDeliveryProduction,runDeliveryProduction}=require('./production') as typeof import('./production');
|
|
96
|
+
const options=record.options as ProductionOptions,ready=inspectDeliveryProduction(options);if(ready.status!=='ready')throw Error('Production preparation pending');
|
|
97
|
+
if(o['export-calldata']){const result:any=await runDeliveryProduction('export-calldata',options);return {status:result.status,executionId,deliveryFile:result.deliveryFile??result.export?.deliveryFile};}
|
|
98
|
+
if(!o.execute&&!one('hashes')&&!one('resume'))return {status:'prepared',deploymentId:record.deploymentId,executionId,planHash:ready.plan.planHash,transactions:ready.plan.transactions};
|
|
99
|
+
const store=await openExecutionStore({trustedRoot:sharedDeliveryHostRoot()}),rpc=projectRpc(root,options.target),signer=o.execute?await createTerminalSigner(root,options.target):undefined,host={store,provider:rpc,finality:{kind:'rpc_finalized' as const},signer,approval,assertCurrent(){}};
|
|
100
|
+
for(let n=0;n<ready.plan.transactions.length*3+3;n++){
|
|
101
|
+
const reconciled:any=await runDeliveryProduction('verify',options,host,{hashes});if(reconciled.status==='accepted'||reconciled.status==='finalization-required'||!o.execute)return {status:reconciled.status,executionId,acceptance:reconciled.acceptance,error:reconciled.error};
|
|
102
|
+
const snapshot=await store.readExecution(executionId),tx=snapshot?.transactions[snapshot.completedCount];
|
|
103
|
+
if(tx&&['submission-uncertain','included-unfinalized'].includes(tx.state))return {status:'pending',executionId};
|
|
104
|
+
const frozen:any=await freezeDeliveryProduction(options,host);if(frozen.status!=='frozen')return {status:frozen.status,executionId};await runDeliveryProduction('execute',options,host,{unsigned:frozen.unsigned});
|
|
105
|
+
}throw Error('Production progress requires resume');
|
|
106
|
+
}
|
|
107
|
+
const aggregate=json(root,record.aggregatePath),plan=aggregate.collections[0].plan;
|
|
108
|
+
if(fs.existsSync(path.join(root,`.gate-delivery/development/${executionId}.superseded.json`)))throw Error('Preparation superseded; resume its replacement execution');
|
|
109
|
+
if(!plan.transactions.length)return {status:'read-only',deploymentId:record.deploymentId,executionId,results:aggregate.collections[0].runtimeEvidence.views??[],queries:plan.customBindings.flatMap((c:any)=>c.observations.filter((v:any)=>v.kind==='contract'))};
|
|
110
|
+
if(o['export-calldata'])throw Error('Development external exports require an explicitly confirmed external executor; production exports consume a release');
|
|
111
|
+
if(!o.execute&&!one('hashes')&&!one('resume'))return {status:'prepared',deploymentId:record.deploymentId,executionId,planHash:plan.planHash,parameters:aggregate.inputs.business.parameters[0].resolved.values,transactions:plan.transactions};
|
|
112
|
+
const req=createRequire(path.join(root,'package.json'));process.env.HARDHAT_NETWORK=plan.target;process.env.GATE_DELIVERY_CONTEXT=JSON.stringify(record.source.targets[0].request);req('ts-node/register');const hre=req('hardhat');
|
|
113
|
+
const store=await openExecutionStore({trustedRoot:sharedDeliveryHostRoot()}),rpc=projectRpc(root,plan.target),signer=o.execute?await createTerminalSigner(root,plan.target):undefined,finality={kind:'confirmations' as const,depth:String(Math.max(1,aggregate.inputs.business.targets[0].finality.confirmations))};
|
|
114
|
+
const context={executionId,planHash:plan.planHash,releaseHash:plan.inputsHash,operator:plan.operator,chainId:plan.chainId,target:plan.target,finality,policyHash:semanticHash(finality)};
|
|
115
|
+
const {createDevelopmentDelivery}=require('./development') as typeof import('./development');
|
|
116
|
+
const life=await createDevelopmentDelivery({root,source:record.source,aggregate,target:plan.target,hre,execution:{context,store,signer,approval}});
|
|
117
|
+
for(let n=0;n<plan.transactions.length*3+3;n++){
|
|
118
|
+
const result:any=await life.continue({hashReferences:hashes});if(result.status==='accepted'||!o.execute)return {status:result.status,deploymentId:record.deploymentId,executionId,acceptance:result.acceptance};
|
|
119
|
+
const state=result.execution?.snapshot,tx=state?.transactions[state.completedCount];if(tx&&['submission-uncertain','included-unfinalized'].includes(tx.state))return {status:'pending',executionId};
|
|
120
|
+
if(result.status==='waiting-external-execution')return {status:result.status,executionId};
|
|
121
|
+
const unsigned=await terminalUnsigned(plan,store,rpc);if(!unsigned)throw Error('No executable transaction');await life.continue({unsigned});
|
|
122
|
+
}throw Error('Development progress requires resume');
|
|
123
|
+
}finally{approval.close();}
|
|
124
|
+
}
|
|
@@ -1681,5 +1681,34 @@ export const compilerDependencyPins: Record<string, { integrity: string; payload
|
|
|
1681
1681
|
"zksync-ethers@6.15.0": {
|
|
1682
1682
|
"integrity": "sha512-zafUxA/lysBO+9Wd6B3qNtDElsPwvAc2b4nBc/YiB4QY4H0pIBvV3/JqxHXXTppEo4gyHAX/+M5brW2qb4YnKA==",
|
|
1683
1683
|
"payloadDigest": "d45d1318e4e84fe7016340ada0f06bf601a344561ea5c1693e644f564133ef25"
|
|
1684
|
-
}
|
|
1684
|
+
},
|
|
1685
|
+
"@aws-sdk/client-lambda@3.1165.0": {"integrity":"sha512-PTs7PpG+f35L+DtF4CA25rVBQVtLaC6DJUj1hjWu2EVsbaj9m3zC/qEUOha98fWgk7p4MIVmfbpWaFhb1dLEjw==","payloadDigest":"851a9d4dc9658548ead1e8e50da1526b2cba9cb40ba55dc855553a81f72255d0"},
|
|
1686
|
+
"@aws-sdk/core@3.980.2": {"integrity":"sha512-Q0hqjfLf1zvwB6aY6fi8pYrtgxHs8sqymhXH/iWBZM/wkokjT869Ws4F12nCD2KX3hiAvKku2cZplxM0cydX8A==","payloadDigest":"8266bc9383fb6bc6ba6a0f53e0265156c8f1fbca5fc3df019725f92e7a276bc5"},
|
|
1687
|
+
"@aws-sdk/credential-provider-env@3.972.83": {"integrity":"sha512-6+hlZC2mCIX9XnjO+x3MwJuR9U7whWiiP0CVq3SLrCluueze0Elce40ivWPuH0TArqHBNyF4y62V5clNDCjtVw==","payloadDigest":"116a7c8d57f447c01e944abb97bb2ce48ba5ca11ae49b1a73b1489a7b87fed0d"},
|
|
1688
|
+
"@aws-sdk/credential-provider-http@3.972.85": {"integrity":"sha512-Rm6vdrzm3eUoG+9frOhS9Q93WdqKq/5h+971aeazkTftwbz3AfYlATd7avn9aMkg2AHlafkbewm0yq/3Sc7GYA==","payloadDigest":"cd60149219e38854e8c85b9d45f7bbcd07dd65ec527a81fc20e4381b71edd701"},
|
|
1689
|
+
"@aws-sdk/credential-provider-ini@3.973.28": {"integrity":"sha512-hSXbMSuPeUY1/RjBC9vahy3ADVULVLU/wyGEXeoelVFYEs7Pki3RF37wROlHOmT8c4XARhJhvLLs+65sczEsoA==","payloadDigest":"8ca45e6a01bf41cbb32f205863394046b67fa78a7d75f8e0cddafb2baf2ae035"},
|
|
1690
|
+
"@aws-sdk/credential-provider-login@3.972.90": {"integrity":"sha512-Hzpp8qvA1qcpAB3xX1+VUwmuTJBPh9h5Ju6CdzzESXTym2JvsTR1NmlhmrufkLr5y+Bj5rj/xjtK4gYu1wA6KA==","payloadDigest":"7a2c7a26b4cb6c36526396e47760dea4b60f027b412659f99ee05c41a1ad0934"},
|
|
1691
|
+
"@aws-sdk/credential-provider-node@3.972.95": {"integrity":"sha512-3IIZ78pwRVLy+d2xn1yRAyEXRc2eCYQ9r5zO4QqDQuVHbOHe01nTWGqLkEM5JAp/vA0pmQTjPojg8JZ10C668Q==","payloadDigest":"e757eb342892ed227fd8ea8418cc7ffa9809c8910a2d051b668c1d77b4c70f67"},
|
|
1692
|
+
"@aws-sdk/credential-provider-process@3.972.83": {"integrity":"sha512-XejCj4/jfZuXmH6P3HCP4eW/7rfrxG70RhurqAvyoo8hevgDwLDW8xR79ww8ad+T/ZD7ERK6jV7CCFBLLBhiLQ==","payloadDigest":"7af500e2d66d5fdfc77c1be3c9e0d2a255a13a6dca16ab3bbf61bd3728d9e40a"},
|
|
1693
|
+
"@aws-sdk/credential-provider-sso@3.973.27": {"integrity":"sha512-lM9xX3+0PCW3H4QfIDk0PRlcJCeF7kV2Cv93MhWQgKRhxzdis5m9inBa801X0w+nq+ckzlYYxa4674etFTikvw==","payloadDigest":"a13dc87b3744479020e99943e748cb2b6c68e5a7654fe7ab46407fd61985ec7e"},
|
|
1694
|
+
"@aws-sdk/credential-provider-web-identity@3.972.89": {"integrity":"sha512-4uJ8gF2huGZ6QisO/AeQm7H2+4HXtEJTw0e6lsbc+Qu3YohUErkYGfJlKJWx3ociM6zlxVObiC6etoAKmnafKg==","payloadDigest":"d1bddd28194f8036e028aec7e63068864f96ec2a64fad951734e4c602589379a"},
|
|
1695
|
+
"@aws-sdk/nested-clients@3.998.2": {"integrity":"sha512-T1vNOfMdvdjXU4Nq267iTFoxZ2Bj0vEatkp66j8wBtrpDoX1mBWmxy7RL8O93S2oXo+BFEiXH3nWtLMd0svLnA==","payloadDigest":"81f78db53a0b67124f742213a08bb31f7821655a2f9b45874e347b9823e7ffd5"},
|
|
1696
|
+
"@aws-sdk/signature-v4-multi-region@3.996.52": {"integrity":"sha512-6W6SjGc8OXUhMzNxU1X922ghD+PP1XvzmCk5Scui0jaYsLezycMYR1RaLp5xTIOUrhTXyb4DnAbPr3fBgmdnzg==","payloadDigest":"56e4922e80d14b0a4321fd1f85a3ca8af3a045e43882653b38c51a67d005a2c8"},
|
|
1697
|
+
"@aws-sdk/token-providers@3.1165.0": {"integrity":"sha512-xYE0nhi3LLacRnoSuUzEv6riWczXXeOOoXeMVw97KBHMLmHKqxmc94leV4RMzEK/BNbZfCKmL5FQoOiuIBkp/g==","payloadDigest":"cc21b6b5c47d3ee597b441619e5205d7a93727ed166241f3ba53fffc6a4d4982"},
|
|
1698
|
+
"@aws-sdk/types@3.975.1": {"integrity":"sha512-7rGxUkCB2QPoQOeJmonmAICTN2zrH+fpmi1p4Iwu72lnxNaMhOgqcbpyddifnM1DBb19TWQ1u6z/XjkaFNEDWw==","payloadDigest":"0ca7696409ffcf02c9706bb73d91fa7f6c4d78871f1b1c5efe412a863d8c0189"},
|
|
1699
|
+
"@aws-sdk/xml-builder@3.972.43": {"integrity":"sha512-rG8QVx4DOrJWptsogu1Aq+CDsnPKaBrAlJpKLxrJrIDXAq1ElnW0yQjjBnlWSXll0cDakCG6UDvaqwz0A9d9Og==","payloadDigest":"4119cc85a701f29fd855b9df5b8b28e1cfe5afb1a888f54ad81efe8809f7b709"},
|
|
1700
|
+
"@smithy/core@3.39.0": {"integrity":"sha512-JJ/46AWQ4ipS1N2eZmUj7yzIhH8NhQIfAE+dce7NSB6dmFh+7hvD4pbofcoT4I0Xzfy/LNhZx3V2QhwYyAiqdg==","payloadDigest":"7783e5236ac39abd0c45cbead262cd32b115e275377dc675e45b43c8feeb75a4"},
|
|
1701
|
+
"@smithy/fetch-http-handler@5.8.1": {"integrity":"sha512-h8BdMUrUBhMhMaeK7QqAdINRZezCGuYOCpcOZZ1ewxbHST9rdTd09xwNpvLTYfzDRehxQiReK4SKbdYZxBA+ew==","payloadDigest":"cdedb086641e8309dac376ffb724e65568f0d4e003b5f3dbc7c07b2eb3da5b53"},
|
|
1702
|
+
"@smithy/node-http-handler@4.14.2": {"integrity":"sha512-i1uORV1v3qBqP43ayRKzIdm1q5x14tf8N4Dd06/QUX1Szm6VxHMrTsu20X5E63UFsaNZCRjI4SXG0jDmqYa+3w==","payloadDigest":"b3ce97b6db1ce15ba8da160da8410bc14417864be60fc4365cb8a148c23691e8"},
|
|
1703
|
+
"@smithy/signature-v4@5.7.5": {"integrity":"sha512-WPjdr5oWOk1LArpI4pavu+fSo+/evi0Re1olxGvqwuZopd4gYR1UGCi+Soyn/IjmafqbWs+ZC+3AKxJS3ZpwUg==","payloadDigest":"000dfc29e577e770862895d65326e0ea4fb1efa6db072251d60bd9ea897ade68"},
|
|
1704
|
+
"@smithy/types@4.20.0": {"integrity":"sha512-lCA6QG22dPk9ecHbv91jDQZsmtPUjdS1aE2Il6NNPqe7DrYc0dZQi6DhcESk2KYXH2sp5xbAcGdYMZDFnuzA2A==","payloadDigest":"43974037f10c563213cbca00e474967504c633d6218ee55b0807b40a64521063"},
|
|
1705
|
+
"ansi-regex@6.6.0": {"integrity":"sha512-XZ5apbzreCbXSKwPjJstu8R0zOi247w3XYwWxtwBXgpZrCyc1Ka7p9/xY0A9/diMewmHbEKz+FIraWaEWjlN5g==","payloadDigest":"dbd037271f0bc6530ac211ca65c029743a92bd9bb586977f2eabeab2541b881d"},
|
|
1706
|
+
"axios@1.21.1": {"integrity":"sha512-6eI5Q/Y4u/Um9dDlsRoq5pY2rxnUTv+L4PpLitnbk/i4jb3MxLZ5CsN5Ih3IysbeRYK4pR+P7qfMsOQl9fwwFQ==","payloadDigest":"cf37451cd3280a2903b7cb94493b92d9f4a8d04f5ce8449adb95469623efd2ea"},
|
|
1707
|
+
"bowser@2.15.0": {"integrity":"sha512-xic6KSZglg/I4ymp45fdM4GWfYpBK79Fxd/TOvJktlaPgQqqDxvmGwOPZl2V0dyeS3Lj5c180bLhXF43iyAjZQ==","payloadDigest":"505bc19d600897f1811261c87a9deda1bafe81802f9fc1098034c877dffba610"},
|
|
1708
|
+
"follow-redirects@1.16.3": {"integrity":"sha512-toOSoqN6d51Wjf1aOFJYcoVv1aND9rj/CwjLU0Vz40oDuSpWDayCeKe4JpL5NL0WdFvoOOCI3BRo69HahjbR1A==","payloadDigest":"f4e2cffd99253e2c00ba7633325ec5452641a4b316411db4e17c8e256762e1ff"},
|
|
1709
|
+
"semver@5.7.3": {"integrity":"sha512-kM18BPOqTi0+TB68703/GJRpAML5Me+IDQsR1J26YB3EFKKNEyHIVZuWDX7+WKQB3tHwDwgk24BfhdpWUbytvQ==","payloadDigest":"14e1e87c08a9cff975c0f6801a8a1b380df34da5714fa73efadaec87706316d7"},
|
|
1710
|
+
"semver@6.3.2": {"integrity":"sha512-GYrCADwpu6yV5OAvchkQ27Z5wwMxWAEMg5NNWjyHh/5DboFFqbdbvYNIvZouQpxXyeMPoTOh0vdPYKlf0ZswdQ==","payloadDigest":"644bcff9dd59be70239d168c15ff0cb793cc0ed1b56596fc3b84b2d905a2c6c1"},
|
|
1711
|
+
"semver@7.8.6": {"integrity":"sha512-9lpSSU4Mly3mrtruwLs1eLK6+gzbzqeBFwRNjIjE+9LuDpWdYctrQlQ3ej1Ilgi7gknpsTRnPoLP8DpCHqHIJw==","payloadDigest":"c54e2cf8301fa13959b3dda2a007630a3bc437c4069052032afc93dbe7585e6e"},
|
|
1712
|
+
"tslib@2.9.1": {"integrity":"sha512-a4Ux9VKuIMHsOS7ENbEq6hK2ZGYIT27Rtl0E4eD9KqwxhKiQeMZE/9xb3IdYwWaSOyIBQLExhQgXDTYoiCxnWA==","payloadDigest":"7b22b4fd35ec1fb499d8edf3ec9a3ac7ea2f43b31c7376668589741148e66226"},
|
|
1713
|
+
"undici@6.29.1": {"integrity":"sha512-EvRlUt/QqAEvXdQeRMYUfwOQsfzpDztykrG2owGEE/rBOBoYv9uF39ZzsNDh4lTFHhTr2XOZjKkYgueD12ZmGA==","payloadDigest":"c689ab0adc7e300af86f8e8a270476da0a3faa0851a30f539a9bcdad0026a000"}
|
|
1685
1714
|
};
|