@agoric/deploy-script-support 0.10.3 → 0.10.4-calypso-dev-84eb287.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +106 -2
- package/package.json +30 -24
- package/src/coreProposalBehavior.js +121 -64
- package/src/endo-pieces-contract.js +3 -0
- package/src/externalTypes.js +20 -17
- package/src/extract-proposal.js +235 -154
- package/src/getBundlerMaker.js +4 -0
- package/src/helpers.js +13 -3
- package/src/install.js +2 -11
- package/src/offer.js +5 -6
- package/src/saveIssuer.js +2 -2
- package/src/startInstance.js +3 -4
- package/src/writeCoreEvalParts.js +227 -0
- package/CHANGELOG.md +0 -538
- package/exported.js +0 -3
- package/src/writeCoreProposal.js +0 -139
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import { E } from '@endo/far';
|
|
4
|
+
import { deeplyFulfilled } from '@endo/marshal';
|
|
5
|
+
|
|
6
|
+
import { createBundles } from '@agoric/internal/src/node/createBundles.js';
|
|
7
|
+
import { defangAndTrim, mergePermits, stringify } from './code-gen.js';
|
|
8
|
+
import {
|
|
9
|
+
makeCoreProposalBehavior,
|
|
10
|
+
permits as defaultPermits,
|
|
11
|
+
} from './coreProposalBehavior.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @import {CoreEvalDescriptor} from './externalTypes.js';
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @typedef CoreEvalPlan
|
|
19
|
+
* @property {string} name
|
|
20
|
+
* @property {string} permit
|
|
21
|
+
* @property {string} script
|
|
22
|
+
* @property {{entrypoint: string, bundleID: string, fileName: string}[]} bundles
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @callback WriteCoreEval write to disk the files needed for a CoreEval (js code to`${filePrefix}.js`, permits to `${filePrefix}-permit.json`, an overall
|
|
27
|
+
* summary to `${filePrefix}-plan.json), plus whatever bundles bundles the code loads)
|
|
28
|
+
* see CoreEval in {@link '/golang/cosmos/x/swingset/types/swingset.pb.go'}
|
|
29
|
+
* @param {string} filePrefix name on disk
|
|
30
|
+
* @param {import('./externalTypes.js').CoreEvalBuilder} builder
|
|
31
|
+
* @returns {Promise<CoreEvalPlan>}
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
*
|
|
36
|
+
* @param {*} homeP
|
|
37
|
+
* @param {{
|
|
38
|
+
* bundleSource: (path: string) => Promise<NodeModule>,
|
|
39
|
+
* pathResolve: (path: string) => string,
|
|
40
|
+
* }} endowments
|
|
41
|
+
* @param {{
|
|
42
|
+
* getBundlerMaker: () => Promise<import('./getBundlerMaker.js').BundleMaker>,
|
|
43
|
+
* getBundleSpec: (...args: *) => Promise<import('./externalTypes.js').ManifestBundleRef>,
|
|
44
|
+
* log?: typeof console.log,
|
|
45
|
+
* writeFile?: typeof fs.promises.writeFile
|
|
46
|
+
* }} io
|
|
47
|
+
* @returns {WriteCoreEval}
|
|
48
|
+
*/
|
|
49
|
+
export const makeWriteCoreEval = (
|
|
50
|
+
homeP,
|
|
51
|
+
endowments,
|
|
52
|
+
{
|
|
53
|
+
getBundlerMaker,
|
|
54
|
+
getBundleSpec,
|
|
55
|
+
log = console.log,
|
|
56
|
+
writeFile = fs.promises.writeFile,
|
|
57
|
+
},
|
|
58
|
+
) => {
|
|
59
|
+
const { bundleSource, pathResolve } = endowments;
|
|
60
|
+
|
|
61
|
+
let bundlerCache;
|
|
62
|
+
/** @returns {import('./getBundlerMaker.js').Bundler} */
|
|
63
|
+
const getBundler = () => {
|
|
64
|
+
if (!bundlerCache) {
|
|
65
|
+
bundlerCache = E(getBundlerMaker()).makeBundler({
|
|
66
|
+
zoe: E.get(homeP).zoe,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
return bundlerCache;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
*
|
|
74
|
+
* @param {CoreEvalDescriptor} coreEval
|
|
75
|
+
* @param {*} additionalPermits
|
|
76
|
+
*/
|
|
77
|
+
const mergeEvalPermit = async (coreEval, additionalPermits) => {
|
|
78
|
+
const {
|
|
79
|
+
sourceSpec,
|
|
80
|
+
getManifestCall: [manifestGetterName, ...manifestGetterArgs],
|
|
81
|
+
} = coreEval;
|
|
82
|
+
|
|
83
|
+
const moduleNamespace = await import(pathResolve(sourceSpec));
|
|
84
|
+
|
|
85
|
+
// We only care about the manifest, not any restoreRef calls.
|
|
86
|
+
const { manifest } = await moduleNamespace[manifestGetterName](
|
|
87
|
+
harden({ restoreRef: x => `restoreRef:${x}` }),
|
|
88
|
+
...manifestGetterArgs,
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
const mergedPermits = mergePermits(manifest);
|
|
92
|
+
return {
|
|
93
|
+
manifest,
|
|
94
|
+
permits: mergePermits({ mergedPermits, additionalPermits }),
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
let mutex =
|
|
99
|
+
/** @type {Promise<import('./externalTypes.js').ManifestBundleRef | undefined>} */ (
|
|
100
|
+
Promise.resolve()
|
|
101
|
+
);
|
|
102
|
+
/** @type {WriteCoreEval} */
|
|
103
|
+
const writeCoreEval = async (filePrefix, builder) => {
|
|
104
|
+
/**
|
|
105
|
+
*
|
|
106
|
+
* @param {string} entrypoint
|
|
107
|
+
* @param {string} [bundlePath]
|
|
108
|
+
* @returns {Promise<NodeModule>}
|
|
109
|
+
*/
|
|
110
|
+
const getBundle = async (entrypoint, bundlePath) => {
|
|
111
|
+
if (!bundlePath) {
|
|
112
|
+
return bundleSource(pathResolve(entrypoint));
|
|
113
|
+
}
|
|
114
|
+
const bundleCache = pathResolve(bundlePath);
|
|
115
|
+
await createBundles([[pathResolve(entrypoint), bundleCache]]);
|
|
116
|
+
const ns = await import(bundleCache);
|
|
117
|
+
return ns.default;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const bundles = [];
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Install an entrypoint.
|
|
124
|
+
*
|
|
125
|
+
* @param {string} entrypoint
|
|
126
|
+
* @param {string} [bundlePath]
|
|
127
|
+
* @param {unknown} [opts]
|
|
128
|
+
* @returns {Promise<import('./externalTypes.js').ManifestBundleRef>}
|
|
129
|
+
*/
|
|
130
|
+
const install = async (entrypoint, bundlePath, opts) => {
|
|
131
|
+
const bundle = getBundle(entrypoint, bundlePath);
|
|
132
|
+
|
|
133
|
+
// Serialise the installations.
|
|
134
|
+
mutex = E.when(mutex, async () => {
|
|
135
|
+
// console.log('installing', { filePrefix, entrypoint, bundlePath });
|
|
136
|
+
const spec = await getBundleSpec(bundle, getBundler, opts);
|
|
137
|
+
bundles.push({
|
|
138
|
+
entrypoint,
|
|
139
|
+
...spec,
|
|
140
|
+
});
|
|
141
|
+
return spec;
|
|
142
|
+
});
|
|
143
|
+
// @ts-expect-error xxx mutex type narrowing
|
|
144
|
+
return mutex;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
// Await a reference then publish to the board.
|
|
148
|
+
const cmds = [];
|
|
149
|
+
/** @param {Promise<import('./externalTypes.js').ManifestBundleRef>} refP */
|
|
150
|
+
const publishRef = async refP => {
|
|
151
|
+
const { fileName, ...ref } = await refP;
|
|
152
|
+
if (fileName) {
|
|
153
|
+
cmds.push(`agd tx swingset install-bundle @${fileName}`);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return harden(ref);
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
// Create the eval structure.
|
|
160
|
+
const evalDescriptor = await deeplyFulfilled(
|
|
161
|
+
harden(builder({ publishRef, install })),
|
|
162
|
+
);
|
|
163
|
+
const { sourceSpec, getManifestCall } = evalDescriptor;
|
|
164
|
+
// console.log('created', { filePrefix, sourceSpec, getManifestCall });
|
|
165
|
+
|
|
166
|
+
// Extract the top-level permit.
|
|
167
|
+
const { permits: evalPermits, manifest: customManifest } =
|
|
168
|
+
await mergeEvalPermit(evalDescriptor, defaultPermits);
|
|
169
|
+
|
|
170
|
+
// Get an install
|
|
171
|
+
const manifestBundleRef = await publishRef(install(sourceSpec));
|
|
172
|
+
|
|
173
|
+
// console.log('writing', { filePrefix, manifestBundleRef, sourceSpec });
|
|
174
|
+
const code = `\
|
|
175
|
+
// This is generated by writeCoreEval; please edit!
|
|
176
|
+
/* eslint-disable */
|
|
177
|
+
|
|
178
|
+
const manifestBundleRef = ${stringify(manifestBundleRef)};
|
|
179
|
+
const getManifestCall = harden(${stringify(getManifestCall, true)});
|
|
180
|
+
const customManifest = ${stringify(customManifest, true)};
|
|
181
|
+
|
|
182
|
+
// Make a behavior function and "export" it by way of script completion value.
|
|
183
|
+
// It is constructed by an anonymous invocation to ensure the absence of a global binding
|
|
184
|
+
// for makeCoreProposalBehavior, which may not be necessary but preserves behavior pre-dating
|
|
185
|
+
// https://github.com/Agoric/agoric-sdk/pull/8712 .
|
|
186
|
+
const behavior = (${makeCoreProposalBehavior})({ manifestBundleRef, getManifestCall, customManifest, E });
|
|
187
|
+
behavior;
|
|
188
|
+
`;
|
|
189
|
+
|
|
190
|
+
const trimmed = defangAndTrim(code);
|
|
191
|
+
|
|
192
|
+
const permitFile = `${filePrefix}-permit.json`;
|
|
193
|
+
log(`creating ${permitFile}`);
|
|
194
|
+
await writeFile(permitFile, JSON.stringify(evalPermits, null, 2));
|
|
195
|
+
|
|
196
|
+
const codeFile = `${filePrefix}.js`;
|
|
197
|
+
log(`creating ${codeFile}`);
|
|
198
|
+
await writeFile(codeFile, trimmed);
|
|
199
|
+
|
|
200
|
+
/** @type {CoreEvalPlan} */
|
|
201
|
+
const plan = {
|
|
202
|
+
name: filePrefix,
|
|
203
|
+
script: codeFile,
|
|
204
|
+
permit: permitFile,
|
|
205
|
+
bundles,
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
await writeFile(
|
|
209
|
+
`${filePrefix}-plan.json`,
|
|
210
|
+
`${JSON.stringify(plan, null, 2)}\n`,
|
|
211
|
+
);
|
|
212
|
+
|
|
213
|
+
log(`\
|
|
214
|
+
You can now run a governance submission command like:
|
|
215
|
+
agd tx gov submit-proposal swingset-core-eval ${permitFile} ${codeFile} \\
|
|
216
|
+
--title="Enable <something>" --description="Evaluate ${codeFile}" --deposit=1000000ubld \\
|
|
217
|
+
--gas=auto --gas-adjustment=1.2
|
|
218
|
+
Remember to install bundles before submitting the proposal:
|
|
219
|
+
${cmds.join('\n ')}
|
|
220
|
+
`);
|
|
221
|
+
return plan;
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
return writeCoreEval;
|
|
225
|
+
};
|
|
226
|
+
/** @deprecated use makeWriteCoreEval */
|
|
227
|
+
export const makeWriteCoreProposal = makeWriteCoreEval;
|