@agoric/deploy-script-support 0.10.4-other-dev-8f8782b.0 → 0.10.4-other-dev-fbe72e7.0.fbe72e7
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 +120 -2
- package/package.json +34 -27
- package/src/assertOfferResult.js +5 -1
- package/src/cachedBundleSpec.js +4 -1
- package/src/coreProposalBehavior.js +122 -64
- package/src/depositInvitation.js +5 -0
- package/src/endo-pieces-contract.js +4 -2
- package/src/externalTypes.js +63 -17
- package/src/extract-proposal.js +229 -154
- package/src/getBundlerMaker.js +4 -0
- package/src/helpers.js +22 -3
- package/src/install.js +2 -11
- package/src/offer.js +10 -7
- package/src/parseCoreEvalArgs.js +36 -0
- package/src/permissioned-deployment.js +168 -0
- package/src/saveIssuer.js +5 -2
- package/src/startInstance.js +8 -5
- package/src/writeCoreEvalParts.js +228 -0
- package/CHANGELOG.md +0 -546
- package/exported.js +0 -3
- package/src/writeCoreProposal.js +0 -139
package/src/extract-proposal.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
+
import { Fail } from '@endo/errors';
|
|
2
3
|
import { deeplyFulfilledObject } from '@agoric/internal';
|
|
3
4
|
import fs from 'fs';
|
|
4
5
|
import { createRequire } from 'module';
|
|
@@ -11,21 +12,45 @@ import {
|
|
|
11
12
|
} from './coreProposalBehavior.js';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
|
-
* @typedef {string | {
|
|
15
|
+
* @typedef {string | {module: string, entrypoint?: string, args?: Array<unknown>}} ConfigProposal
|
|
15
16
|
*/
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
/**
|
|
19
|
+
* @typedef {{steps: ConfigProposal[][]}} SequentialCoreProposals
|
|
20
|
+
* @typedef {ConfigProposal[] | SequentialCoreProposals} CoreProposals
|
|
21
|
+
*/
|
|
18
22
|
|
|
19
23
|
const req = createRequire(import.meta.url);
|
|
20
24
|
|
|
25
|
+
/**
|
|
26
|
+
* @param {...(CoreProposals | undefined | null)} args
|
|
27
|
+
* @returns {SequentialCoreProposals}
|
|
28
|
+
*/
|
|
29
|
+
export const mergeCoreProposals = (...args) => {
|
|
30
|
+
/** @type {ConfigProposal[][]} */
|
|
31
|
+
const steps = [];
|
|
32
|
+
for (const coreProposal of args) {
|
|
33
|
+
if (!coreProposal) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
if ('steps' in coreProposal) {
|
|
37
|
+
steps.push(...coreProposal.steps);
|
|
38
|
+
} else {
|
|
39
|
+
steps.push(coreProposal);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return harden({ steps });
|
|
43
|
+
};
|
|
44
|
+
harden(mergeCoreProposals);
|
|
45
|
+
|
|
21
46
|
/**
|
|
22
47
|
* @param {(ModuleSpecifier | FilePath)[]} paths
|
|
23
48
|
* @typedef {string} ModuleSpecifier
|
|
24
49
|
* @typedef {string} FilePath
|
|
25
50
|
*/
|
|
26
51
|
const pathResolve = (...paths) => {
|
|
27
|
-
const fileName = paths.pop();
|
|
28
|
-
|
|
52
|
+
const fileName = /** @type {string} */ (paths.pop());
|
|
53
|
+
fileName || Fail`base name required`;
|
|
29
54
|
try {
|
|
30
55
|
return req.resolve(fileName, {
|
|
31
56
|
paths,
|
|
@@ -40,6 +65,19 @@ const findModule = (initDir, srcSpec) =>
|
|
|
40
65
|
? pathResolve(initDir, srcSpec)
|
|
41
66
|
: req.resolve(srcSpec);
|
|
42
67
|
|
|
68
|
+
/**
|
|
69
|
+
* @param {{ bundleID?: string, bundleName?: string }} handle - mutated then hardened
|
|
70
|
+
* @param {string} sourceSpec - the specifier of a module to load
|
|
71
|
+
* @param {string} key - the key of the proposal
|
|
72
|
+
* @param {string} piece - the piece of the proposal
|
|
73
|
+
* @returns {Promise<[string, any]>}
|
|
74
|
+
*/
|
|
75
|
+
const namedHandleToBundleSpec = async (handle, sourceSpec, key, piece) => {
|
|
76
|
+
handle.bundleName = `coreProposal${String(key)}_${piece}`;
|
|
77
|
+
harden(handle);
|
|
78
|
+
return harden([handle.bundleName, { sourceSpec }]);
|
|
79
|
+
};
|
|
80
|
+
|
|
43
81
|
/**
|
|
44
82
|
* Format core proposals to be run at bootstrap:
|
|
45
83
|
* SwingSet `bundles` configuration
|
|
@@ -51,188 +89,225 @@ const findModule = (initDir, srcSpec) =>
|
|
|
51
89
|
* but for sim-chain and such, they can be declared statically in
|
|
52
90
|
* the chain configuration, in which case they are run at bootstrap.
|
|
53
91
|
*
|
|
54
|
-
* @param {
|
|
92
|
+
* @param {CoreProposals} coreProposals - governance
|
|
55
93
|
* proposals to run at chain bootstrap for scenarios such as sim-chain.
|
|
56
94
|
* @param {FilePath} [dirname]
|
|
57
|
-
* @param {
|
|
58
|
-
* @param {
|
|
95
|
+
* @param {object} [opts]
|
|
96
|
+
* @param {typeof makeEnactCoreProposalsFromBundleRef} [opts.makeEnactCoreProposals]
|
|
97
|
+
* @param {(key: PropertyKey) => PropertyKey} [opts.getSequenceForProposal]
|
|
98
|
+
* @param {typeof namedHandleToBundleSpec} [opts.handleToBundleSpec]
|
|
59
99
|
*/
|
|
60
100
|
export const extractCoreProposalBundles = async (
|
|
61
101
|
coreProposals,
|
|
62
102
|
dirname = '.',
|
|
63
|
-
|
|
64
|
-
getSequenceForProposal,
|
|
103
|
+
opts,
|
|
65
104
|
) => {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
getSequenceForProposal =
|
|
69
|
-
|
|
105
|
+
const {
|
|
106
|
+
makeEnactCoreProposals = makeEnactCoreProposalsFromBundleRef,
|
|
107
|
+
getSequenceForProposal = key => key,
|
|
108
|
+
handleToBundleSpec = namedHandleToBundleSpec,
|
|
109
|
+
} = opts || {};
|
|
70
110
|
|
|
71
111
|
dirname = pathResolve(dirname);
|
|
72
112
|
dirname = await fs.promises
|
|
73
113
|
.stat(dirname)
|
|
74
114
|
.then(stbuf => (stbuf.isDirectory() ? dirname : path.dirname(dirname)));
|
|
75
115
|
|
|
76
|
-
/** @type {Map<{ bundleName?: string }, { source: string, bundle?: string }>} */
|
|
116
|
+
/** @type {Map<{ bundleID?: string, bundleName?: string }, { source: string, bundle?: string }>} */
|
|
77
117
|
const bundleHandleToAbsolutePaths = new Map();
|
|
78
118
|
|
|
119
|
+
const proposalSteps =
|
|
120
|
+
'steps' in coreProposals ? coreProposals.steps : [coreProposals];
|
|
79
121
|
const bundleToSource = new Map();
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
typeof module === 'string' ||
|
|
99
|
-
Fail`coreProposal module ${module} must be string`;
|
|
100
|
-
typeof entrypoint === 'string' ||
|
|
101
|
-
Fail`coreProposal entrypoint ${entrypoint} must be string`;
|
|
102
|
-
Array.isArray(args) || Fail`coreProposal args ${args} must be array`;
|
|
103
|
-
|
|
104
|
-
const thisProposalBundleHandles = new Set();
|
|
105
|
-
assert(getSequenceForProposal);
|
|
106
|
-
const thisProposalSequence = getSequenceForProposal(i);
|
|
107
|
-
const initPath = findModule(dirname, module);
|
|
108
|
-
const initDir = path.dirname(initPath);
|
|
109
|
-
/** @type {Record<string, import('./externalTypes.js').ProposalBuilder>} */
|
|
110
|
-
const ns = await import(initPath);
|
|
111
|
-
const install = (srcSpec, bundlePath) => {
|
|
112
|
-
const absoluteSrc = findModule(initDir, srcSpec);
|
|
113
|
-
const bundleHandle = {};
|
|
114
|
-
const absolutePaths = { source: absoluteSrc };
|
|
115
|
-
if (bundlePath) {
|
|
116
|
-
const absoluteBundle = pathResolve(initDir, bundlePath);
|
|
117
|
-
absolutePaths.bundle = absoluteBundle;
|
|
118
|
-
const oldSource = bundleToSource.get(absoluteBundle);
|
|
119
|
-
if (oldSource) {
|
|
120
|
-
assert.equal(
|
|
121
|
-
oldSource,
|
|
122
|
-
absoluteSrc,
|
|
123
|
-
X`${bundlePath} already installed from ${oldSource}, now ${absoluteSrc}`,
|
|
124
|
-
);
|
|
122
|
+
const extractedSteps = await Promise.all(
|
|
123
|
+
proposalSteps.map((proposalStep, i) =>
|
|
124
|
+
Promise.all(
|
|
125
|
+
proposalStep.map(async (coreProposal, j) => {
|
|
126
|
+
const key = `${i}.${j}`;
|
|
127
|
+
// console.debug(`Parsing core proposal:`, coreProposal);
|
|
128
|
+
|
|
129
|
+
/** @type {string} */
|
|
130
|
+
let entrypoint;
|
|
131
|
+
/** @type {unknown[]} */
|
|
132
|
+
let args;
|
|
133
|
+
/** @type {string} */
|
|
134
|
+
let module;
|
|
135
|
+
if (typeof coreProposal === 'string') {
|
|
136
|
+
module = coreProposal;
|
|
137
|
+
entrypoint = 'defaultProposalBuilder';
|
|
138
|
+
args = [];
|
|
125
139
|
} else {
|
|
126
|
-
|
|
140
|
+
({
|
|
141
|
+
module,
|
|
142
|
+
entrypoint = 'defaultProposalBuilder',
|
|
143
|
+
args = [],
|
|
144
|
+
} = coreProposal);
|
|
127
145
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
146
|
+
|
|
147
|
+
typeof module === 'string' ||
|
|
148
|
+
Fail`coreProposal module ${module} must be string`;
|
|
149
|
+
typeof entrypoint === 'string' ||
|
|
150
|
+
Fail`coreProposal entrypoint ${entrypoint} must be string`;
|
|
151
|
+
Array.isArray(args) || Fail`coreProposal args ${args} must be array`;
|
|
152
|
+
|
|
153
|
+
const thisProposalBundleHandles = new Set();
|
|
154
|
+
assert(getSequenceForProposal);
|
|
155
|
+
const thisProposalSequence = getSequenceForProposal(key);
|
|
156
|
+
const initPath = findModule(dirname, module);
|
|
157
|
+
const initDir = path.dirname(initPath);
|
|
158
|
+
/** @type {Record<string, import('./externalTypes.js').CoreEvalBuilder>} */
|
|
159
|
+
const ns = await import(initPath);
|
|
160
|
+
const install = (srcSpec, bundlePath) => {
|
|
161
|
+
const absoluteSrc = findModule(initDir, srcSpec);
|
|
162
|
+
const bundleHandle = {};
|
|
163
|
+
const absolutePaths = { source: absoluteSrc };
|
|
164
|
+
if (bundlePath) {
|
|
165
|
+
const absoluteBundle = pathResolve(initDir, bundlePath);
|
|
166
|
+
absolutePaths.bundle = absoluteBundle;
|
|
167
|
+
const oldSource = bundleToSource.get(absoluteBundle);
|
|
168
|
+
if (oldSource) {
|
|
169
|
+
oldSource === absoluteSrc ||
|
|
170
|
+
Fail`${bundlePath} already installed from ${oldSource}, now ${absoluteSrc}`;
|
|
171
|
+
} else {
|
|
172
|
+
bundleToSource.set(absoluteBundle, absoluteSrc);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// Don't harden the bundleHandle since we need to set the bundleName on
|
|
176
|
+
// its unique identity later.
|
|
177
|
+
thisProposalBundleHandles.add(bundleHandle);
|
|
178
|
+
bundleHandleToAbsolutePaths.set(
|
|
179
|
+
bundleHandle,
|
|
180
|
+
harden(absolutePaths),
|
|
181
|
+
);
|
|
182
|
+
return bundleHandle;
|
|
183
|
+
};
|
|
184
|
+
/** @type {import('./externalTypes.js').PublishBundleRef} */
|
|
185
|
+
const publishRef = async handleP => {
|
|
186
|
+
const handle = await handleP;
|
|
187
|
+
bundleHandleToAbsolutePaths.has(handle) ||
|
|
188
|
+
Fail`${handle} not in installed bundles`;
|
|
189
|
+
return handle;
|
|
190
|
+
};
|
|
191
|
+
const proposal = await ns[entrypoint](
|
|
192
|
+
{
|
|
193
|
+
publishRef,
|
|
194
|
+
// @ts-expect-error not statically verified to return a full obj
|
|
195
|
+
install,
|
|
196
|
+
},
|
|
197
|
+
...args,
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
// Add the proposal bundle handles in sorted order.
|
|
201
|
+
const bundleSpecEntries = await Promise.all(
|
|
202
|
+
[...thisProposalBundleHandles.keys()]
|
|
203
|
+
.map(handle => [handle, bundleHandleToAbsolutePaths.get(handle)])
|
|
204
|
+
.sort(([_hnda, { source: a }], [_hndb, { source: b }]) => {
|
|
205
|
+
if (a < b) {
|
|
206
|
+
return -1;
|
|
207
|
+
}
|
|
208
|
+
if (a > b) {
|
|
209
|
+
return 1;
|
|
210
|
+
}
|
|
211
|
+
return 0;
|
|
212
|
+
})
|
|
213
|
+
.map(async ([handle, absolutePaths], k) => {
|
|
214
|
+
// Transform the bundle handle identity into a bundleName reference.
|
|
215
|
+
const specEntry = await handleToBundleSpec(
|
|
216
|
+
handle,
|
|
217
|
+
absolutePaths.source,
|
|
218
|
+
thisProposalSequence,
|
|
219
|
+
String(k),
|
|
220
|
+
);
|
|
221
|
+
harden(handle);
|
|
222
|
+
return specEntry;
|
|
223
|
+
}),
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
// Now that we've assigned all the bundleNames and hardened the
|
|
227
|
+
// handles, we can extract the behavior bundle.
|
|
228
|
+
const { sourceSpec, getManifestCall } = await deeplyFulfilledObject(
|
|
229
|
+
harden(proposal),
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
const proposalSource = pathResolve(initDir, sourceSpec);
|
|
233
|
+
const proposalNS = await import(proposalSource);
|
|
234
|
+
const [manifestGetterName, ...manifestGetterArgs] = getManifestCall;
|
|
235
|
+
manifestGetterName in proposalNS ||
|
|
236
|
+
Fail`proposal ${proposalSource} missing export ${manifestGetterName}`;
|
|
237
|
+
const { manifest: customManifest } = await proposalNS[
|
|
238
|
+
manifestGetterName
|
|
239
|
+
](harden({ restoreRef: () => null }), ...manifestGetterArgs);
|
|
240
|
+
|
|
241
|
+
const behaviorBundleHandle = {};
|
|
242
|
+
const specEntry = await handleToBundleSpec(
|
|
243
|
+
behaviorBundleHandle,
|
|
244
|
+
proposalSource,
|
|
245
|
+
thisProposalSequence,
|
|
246
|
+
'proposalNS',
|
|
247
|
+
);
|
|
248
|
+
bundleSpecEntries.unshift(specEntry);
|
|
249
|
+
|
|
250
|
+
bundleHandleToAbsolutePaths.set(
|
|
251
|
+
behaviorBundleHandle,
|
|
252
|
+
harden({
|
|
253
|
+
source: proposalSource,
|
|
254
|
+
}),
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
return /** @type {const} */ ([
|
|
258
|
+
key,
|
|
259
|
+
{
|
|
260
|
+
ref: behaviorBundleHandle,
|
|
261
|
+
call: getManifestCall,
|
|
262
|
+
customManifest,
|
|
263
|
+
bundleSpecs: bundleSpecEntries,
|
|
264
|
+
},
|
|
265
|
+
]);
|
|
266
|
+
}),
|
|
267
|
+
),
|
|
268
|
+
),
|
|
205
269
|
);
|
|
206
270
|
|
|
207
271
|
// Extract all the bundle specs in already-sorted order.
|
|
208
272
|
const bundles = Object.fromEntries(
|
|
209
|
-
|
|
273
|
+
extractedSteps.flatMap(step =>
|
|
274
|
+
step.flatMap(([_key, { bundleSpecs }]) => bundleSpecs),
|
|
275
|
+
),
|
|
210
276
|
);
|
|
211
277
|
harden(bundles);
|
|
212
278
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
279
|
+
const codeSteps = extractedSteps.map(extractedStep => {
|
|
280
|
+
// Extract the manifest references and calls.
|
|
281
|
+
const metadataRecords = extractedStep.map(([_key, extractedSpec]) => {
|
|
282
|
+
const { ref, call, customManifest } = extractedSpec;
|
|
283
|
+
return { ref, call, customManifest };
|
|
284
|
+
});
|
|
285
|
+
harden(metadataRecords);
|
|
220
286
|
|
|
221
|
-
|
|
222
|
-
// This is generated by @agoric/
|
|
287
|
+
const code = `\
|
|
288
|
+
// This is generated by @agoric/deploy-script-support/src/extract-proposal.js - DO NOT EDIT
|
|
223
289
|
/* eslint-disable */
|
|
224
290
|
|
|
225
|
-
const
|
|
226
|
-
|
|
227
|
-
const makeCoreProposalBehavior = ${makeCoreProposalBehavior};
|
|
291
|
+
const metadataRecords = harden(${stringify(metadataRecords, true)});
|
|
228
292
|
|
|
229
|
-
|
|
293
|
+
// Make an enactCoreProposals function and "export" it by way of script completion value.
|
|
294
|
+
// It is constructed by an IIFE to ensure the absence of global bindings for
|
|
295
|
+
// makeCoreProposalBehavior and makeEnactCoreProposals (the latter referencing the former),
|
|
296
|
+
// which may not be necessary but preserves behavior pre-dating
|
|
297
|
+
// https://github.com/Agoric/agoric-sdk/pull/8712 .
|
|
298
|
+
const enactCoreProposals = ((
|
|
299
|
+
makeCoreProposalBehavior = ${makeCoreProposalBehavior},
|
|
300
|
+
makeEnactCoreProposals = ${makeEnactCoreProposals},
|
|
301
|
+
) => makeEnactCoreProposals({ metadataRecords, E }))();
|
|
302
|
+
enactCoreProposals;
|
|
230
303
|
`;
|
|
304
|
+
return defangAndTrim(code);
|
|
305
|
+
});
|
|
231
306
|
|
|
232
307
|
// console.debug('created bundles from proposals:', coreProposals, bundles);
|
|
233
|
-
return {
|
|
308
|
+
return harden({
|
|
234
309
|
bundles,
|
|
235
|
-
|
|
310
|
+
codeSteps,
|
|
236
311
|
bundleHandleToAbsolutePaths,
|
|
237
|
-
};
|
|
312
|
+
});
|
|
238
313
|
};
|
package/src/getBundlerMaker.js
CHANGED
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
import { E } from '@endo/far';
|
|
14
14
|
import url from 'url';
|
|
15
15
|
|
|
16
|
+
/** @typedef {ReturnType<import('./endo-pieces-contract.js')['start']>['publicFacet']} BundleMaker */
|
|
17
|
+
/** @typedef {ReturnType<BundleMaker['makeBundler']>} Bundler */
|
|
18
|
+
|
|
16
19
|
export const makeGetBundlerMaker =
|
|
17
20
|
(homeP, { lookup, bundleSource }) =>
|
|
18
21
|
async ({
|
|
@@ -20,6 +23,7 @@ export const makeGetBundlerMaker =
|
|
|
20
23
|
log = console.log,
|
|
21
24
|
} = {}) => {
|
|
22
25
|
const { board: optionalBoard, zoe, scratch } = await homeP;
|
|
26
|
+
/** @type {() => Promise<BundleMaker>} */
|
|
23
27
|
const lookupOrCreate = async () => {
|
|
24
28
|
// Locate the bundler maker if any already exists at the given path.
|
|
25
29
|
let bundlerMaker = await lookup(JSON.parse(BUNDLER_MAKER_LOOKUP));
|
package/src/helpers.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
/// <reference path="../../zoe/exported.js" />
|
|
4
|
+
|
|
3
5
|
import { E } from '@endo/far';
|
|
4
6
|
import bundleSource from '@endo/bundle-source';
|
|
5
7
|
|
|
@@ -15,9 +17,10 @@ import { makeSaveIssuer } from './saveIssuer.js';
|
|
|
15
17
|
import { makeGetBundlerMaker } from './getBundlerMaker.js';
|
|
16
18
|
import { assertOfferResult } from './assertOfferResult.js';
|
|
17
19
|
import { installInPieces } from './installInPieces.js';
|
|
18
|
-
import {
|
|
20
|
+
import { makeWriteCoreEval } from './writeCoreEvalParts.js';
|
|
19
21
|
|
|
20
22
|
export * from '@agoric/internal/src/node/createBundles.js';
|
|
23
|
+
export { parseScriptArgs } from './parseCoreEvalArgs.js';
|
|
21
24
|
|
|
22
25
|
// These are also hard-coded in lib-wallet.js.
|
|
23
26
|
// TODO: Add methods to the wallet to access these without hard-coding
|
|
@@ -50,6 +53,10 @@ const makeLazyObject = sourceObject => {
|
|
|
50
53
|
return /** @type {T} */ (lazyObject);
|
|
51
54
|
};
|
|
52
55
|
|
|
56
|
+
/**
|
|
57
|
+
* @param {Promise<import('./externalTypes.js').CommonHome | import('./externalTypes.js').AgSoloHome>} homePromise
|
|
58
|
+
* @param {import('./externalTypes.js').DeployScriptEndownments} endowments
|
|
59
|
+
*/
|
|
53
60
|
export const makeHelpers = async (homePromise, endowments) => {
|
|
54
61
|
// Endowments provided via `agoric run` or `agoric deploy`.
|
|
55
62
|
const {
|
|
@@ -82,6 +89,7 @@ export const makeHelpers = async (homePromise, endowments) => {
|
|
|
82
89
|
return E(deps.walletAdmin).getIssuerManager();
|
|
83
90
|
},
|
|
84
91
|
get offerAndFind() {
|
|
92
|
+
assert('wallet' in deps.home, 'expected AgSolo home');
|
|
85
93
|
return makeOfferAndFindInvitationAmount(
|
|
86
94
|
deps.walletAdmin,
|
|
87
95
|
deps.home.zoe,
|
|
@@ -89,6 +97,7 @@ export const makeHelpers = async (homePromise, endowments) => {
|
|
|
89
97
|
);
|
|
90
98
|
},
|
|
91
99
|
get walletAdmin() {
|
|
100
|
+
assert('wallet' in deps.home, 'expected AgSolo home');
|
|
92
101
|
return E(deps.home.wallet).getAdminFacet();
|
|
93
102
|
},
|
|
94
103
|
get zoeInvitationPurse() {
|
|
@@ -108,6 +117,7 @@ export const makeHelpers = async (homePromise, endowments) => {
|
|
|
108
117
|
return deps.offerAndFind.findInvitationAmount;
|
|
109
118
|
},
|
|
110
119
|
get install() {
|
|
120
|
+
assert('wallet' in deps.home, 'expected AgSolo home');
|
|
111
121
|
return makeInstall(
|
|
112
122
|
bundleSource,
|
|
113
123
|
deps.home.zoe,
|
|
@@ -125,6 +135,7 @@ export const makeHelpers = async (homePromise, endowments) => {
|
|
|
125
135
|
return makeSaveIssuer(deps.walletAdmin, deps.issuerManager);
|
|
126
136
|
},
|
|
127
137
|
get startInstance() {
|
|
138
|
+
assert('wallet' in deps.home, 'expected AgSolo home');
|
|
128
139
|
return makeStartInstance(
|
|
129
140
|
deps.issuerManager,
|
|
130
141
|
deps.instanceManager,
|
|
@@ -135,8 +146,16 @@ export const makeHelpers = async (homePromise, endowments) => {
|
|
|
135
146
|
get getBundlerMaker() {
|
|
136
147
|
return makeGetBundlerMaker(homePromise, { bundleSource, lookup });
|
|
137
148
|
},
|
|
149
|
+
/** @returns {import('./writeCoreEvalParts.js').WriteCoreEval} */
|
|
150
|
+
get writeCoreEval() {
|
|
151
|
+
return makeWriteCoreEval(homePromise, endowments, {
|
|
152
|
+
getBundleSpec: deps.cacheAndGetBundleSpec,
|
|
153
|
+
getBundlerMaker: helpers.getBundlerMaker,
|
|
154
|
+
});
|
|
155
|
+
},
|
|
156
|
+
/** @deprecated use writeCoreEval */
|
|
138
157
|
get writeCoreProposal() {
|
|
139
|
-
return
|
|
158
|
+
return makeWriteCoreEval(homePromise, endowments, {
|
|
140
159
|
getBundleSpec: deps.cacheAndGetBundleSpec,
|
|
141
160
|
getBundlerMaker: helpers.getBundlerMaker,
|
|
142
161
|
});
|
package/src/install.js
CHANGED
|
@@ -3,20 +3,11 @@ import './externalTypes.js';
|
|
|
3
3
|
|
|
4
4
|
import { E } from '@endo/far';
|
|
5
5
|
|
|
6
|
-
/** @
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* @callback BundleSource
|
|
10
|
-
* @param {string} startFilename - the filepath to start the bundling from
|
|
11
|
-
* @param {ModuleFormat | BundleOptions} [moduleFormat]
|
|
12
|
-
* @param {object} [powers]
|
|
13
|
-
* @param {ReadFn} [powers.read]
|
|
14
|
-
* @param {CanonicalFn} [powers.canonical]
|
|
15
|
-
*/
|
|
6
|
+
/** @import {Petname} from '@agoric/deploy-script-support/src/externalTypes.js' */
|
|
16
7
|
|
|
17
8
|
// XXX board is Board but specifying that leads to type errors with imports which aren't worth fixing right now
|
|
18
9
|
/**
|
|
19
|
-
* @param {
|
|
10
|
+
* @param {typeof import('@endo/bundle-source')['default']} bundleSource
|
|
20
11
|
* @param {ERef<ZoeService>} zoe
|
|
21
12
|
* @param {ERef<import('./startInstance.js').InstallationManager>} installationManager
|
|
22
13
|
* @param {ERef<any>} board
|
package/src/offer.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
+
import { assert } from '@endo/errors';
|
|
2
3
|
import { E } from '@endo/far';
|
|
3
|
-
import { assert } from '@agoric/assert';
|
|
4
4
|
// Avoid pulling in too many dependencies like notifiers
|
|
5
5
|
import { AmountMath } from '@agoric/ertp/src/amountMath.js';
|
|
6
6
|
|
|
7
|
-
/**
|
|
7
|
+
/**
|
|
8
|
+
* @import {Petname} from '@agoric/deploy-script-support/src/externalTypes.js';
|
|
9
|
+
* @import {Amount, Brand, Issuer, Payment, Purse} from '@agoric/ertp';
|
|
10
|
+
* @import {InvitationDetails, Keyword, Proposal} from '@agoric/zoe';
|
|
11
|
+
*/
|
|
8
12
|
|
|
9
13
|
/**
|
|
10
14
|
* @typedef {object} OfferHelperConfig
|
|
@@ -19,7 +23,7 @@ import { AmountMath } from '@agoric/ertp/src/amountMath.js';
|
|
|
19
23
|
* @param {ERef<any>} walletAdmin - an internal type of the
|
|
20
24
|
* wallet, not defined here
|
|
21
25
|
* @param {ERef<ZoeService>} zoe
|
|
22
|
-
* @param {ERef<Purse
|
|
26
|
+
* @param {ERef<Purse<'set', InvitationDetails>>} zoeInvitationPurse
|
|
23
27
|
*/
|
|
24
28
|
export const makeOfferAndFindInvitationAmount = (
|
|
25
29
|
walletAdmin,
|
|
@@ -28,7 +32,7 @@ export const makeOfferAndFindInvitationAmount = (
|
|
|
28
32
|
) => {
|
|
29
33
|
/**
|
|
30
34
|
* @param {Record<string, any>} invitationDetailsCriteria
|
|
31
|
-
* @returns {Promise<
|
|
35
|
+
* @returns {Promise<InvitationAmount>} invitationAmount
|
|
32
36
|
*/
|
|
33
37
|
const findInvitationAmount = async invitationDetailsCriteria => {
|
|
34
38
|
const invitationAmount = await E(zoeInvitationPurse).getCurrentAmount();
|
|
@@ -114,9 +118,8 @@ export const makeOfferAndFindInvitationAmount = (
|
|
|
114
118
|
} = config;
|
|
115
119
|
|
|
116
120
|
const invitationToUse = getInvitation(invitation, partialInvitationDetails);
|
|
117
|
-
const invitationDetails =
|
|
118
|
-
invitationToUse
|
|
119
|
-
);
|
|
121
|
+
const invitationDetails =
|
|
122
|
+
await E(zoe).getInvitationDetails(invitationToUse);
|
|
120
123
|
const payments = withdrawPayments(proposal, paymentsWithPursePetnames);
|
|
121
124
|
|
|
122
125
|
const seat = E(zoe).offer(invitationToUse, proposal, payments);
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* To customize proposals for multiple environments, we pass the "variant"
|
|
3
|
+
* identifier in scriptArgs. The variant must match a knownVariant.
|
|
4
|
+
*
|
|
5
|
+
* @param {import('./externalTypes.js').DeployScriptEndownments} endowments
|
|
6
|
+
* @param {string} name a name to use in error messages or Usage suggestions.
|
|
7
|
+
* @param {string[]} knownVariants
|
|
8
|
+
*/
|
|
9
|
+
export const parseScriptArgs = async (endowments, name, knownVariants) => {
|
|
10
|
+
const { scriptArgs } = endowments;
|
|
11
|
+
// const variantOrConfig = scriptArgs?.[0];
|
|
12
|
+
const variantOrConfig =
|
|
13
|
+
scriptArgs && scriptArgs.length > 0 ? scriptArgs : undefined;
|
|
14
|
+
|
|
15
|
+
console.log(`${name}`, variantOrConfig);
|
|
16
|
+
|
|
17
|
+
const Usage = `agoric run ${name}.js ${[...knownVariants, '<json-config>'].join(' | ')}`;
|
|
18
|
+
const opts = {};
|
|
19
|
+
|
|
20
|
+
if (typeof variantOrConfig === 'string') {
|
|
21
|
+
if (variantOrConfig[0] === '{') {
|
|
22
|
+
try {
|
|
23
|
+
opts.config = JSON.parse(variantOrConfig);
|
|
24
|
+
} catch (err) {
|
|
25
|
+
throw Error(`Failed to parse config argument ${variantOrConfig}`);
|
|
26
|
+
}
|
|
27
|
+
} else {
|
|
28
|
+
opts.variant = variantOrConfig;
|
|
29
|
+
}
|
|
30
|
+
} else {
|
|
31
|
+
console.error(Usage);
|
|
32
|
+
throw Error(Usage);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return opts;
|
|
36
|
+
};
|