agoric 0.18.4 → 0.18.5-dev-800c2bb.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 +73 -0
- package/package.json +37 -30
- package/src/bin-agops.js +68 -6
- package/src/chain-config.js +19 -2
- package/src/commands/auction.js +170 -0
- package/src/commands/ec.js +314 -0
- package/src/commands/inter.js +626 -0
- package/src/commands/oracle.js +212 -0
- package/src/commands/perf.js +32 -22
- package/src/commands/psm.js +75 -210
- package/src/commands/reserve.js +98 -0
- package/src/commands/test-upgrade.js +109 -0
- package/src/commands/vaults.js +161 -0
- package/src/commands/wallet.js +85 -60
- package/src/cosmos.js +5 -9
- package/src/deploy.js +208 -334
- package/src/entrypoint.js +9 -2
- package/src/follow.js +40 -4
- package/src/init.js +11 -10
- package/src/install.js +25 -30
- package/src/json-http-client-node.js +2 -2
- package/src/json.js +1 -1
- package/src/lib/casting.js +4 -2
- package/src/lib/chain.js +147 -33
- package/src/lib/format.js +58 -43
- package/src/lib/rpc.js +106 -101
- package/src/lib/wallet.js +305 -10
- package/src/main-publish.js +3 -5
- package/src/main.js +74 -42
- package/src/open.js +3 -1
- package/src/publish.js +25 -23
- package/src/run.js +20 -0
- package/src/scripts.js +190 -0
- package/src/sdk-package-names.js +6 -2
- package/src/set-defaults.js +2 -2
- package/src/start.js +69 -35
- package/src/lib/psm.js +0 -82
package/src/deploy.js
CHANGED
|
@@ -1,19 +1,14 @@
|
|
|
1
|
+
// @ts-check
|
|
1
2
|
/* global process setTimeout setInterval clearInterval */
|
|
2
|
-
/* eslint-disable no-await-in-loop */
|
|
3
3
|
|
|
4
4
|
import { E, makeCapTP } from '@endo/captp';
|
|
5
5
|
import { makePromiseKit } from '@endo/promise-kit';
|
|
6
|
-
import bundleSource from '@endo/bundle-source';
|
|
7
|
-
import { makeCache } from '@agoric/cache';
|
|
8
6
|
import { makeLeaderFromRpcAddresses } from '@agoric/casting';
|
|
9
|
-
import { search as readContainingPackageDescriptor } from '@endo/compartment-mapper';
|
|
10
|
-
import url from 'url';
|
|
11
7
|
import path from 'path';
|
|
12
8
|
import http from 'http';
|
|
13
9
|
import inquirer from 'inquirer';
|
|
14
|
-
import createEsmRequire from 'esm';
|
|
15
|
-
import { createRequire } from 'module';
|
|
16
10
|
import { SigningStargateClient } from '@cosmjs/stargate';
|
|
11
|
+
import { whileTrue } from '@agoric/internal';
|
|
17
12
|
|
|
18
13
|
import { getAccessToken } from '@agoric/access-token';
|
|
19
14
|
|
|
@@ -23,12 +18,10 @@ import {
|
|
|
23
18
|
makeHttpBundlePublisher,
|
|
24
19
|
} from './publish.js';
|
|
25
20
|
import { makeJsonHttpClient } from './json-http-client-node.js';
|
|
21
|
+
import { makeScriptLoader } from './scripts.js';
|
|
26
22
|
|
|
27
23
|
const { details: X } = assert;
|
|
28
24
|
|
|
29
|
-
const require = createRequire(import.meta.url);
|
|
30
|
-
const esmRequire = createEsmRequire({});
|
|
31
|
-
|
|
32
25
|
// note: CapTP has its own HandledPromise instantiation, and the contract
|
|
33
26
|
// must use the same one that CapTP uses. We achieve this by not bundling
|
|
34
27
|
// captp, and doing a (non-isolated) dynamic import of the deploy script
|
|
@@ -43,14 +36,170 @@ const esmRequire = createEsmRequire({});
|
|
|
43
36
|
|
|
44
37
|
const RETRY_DELAY_MS = 1000;
|
|
45
38
|
|
|
46
|
-
const
|
|
39
|
+
const getPort = u =>
|
|
40
|
+
u.port || (['https:', 'wss:'].includes(u.protocol) ? '443' : '80');
|
|
41
|
+
|
|
42
|
+
const connectAndRun = async (
|
|
43
|
+
wsurl,
|
|
44
|
+
main,
|
|
45
|
+
{ need, provide },
|
|
46
|
+
{ makeWebSocket, now, console },
|
|
47
|
+
) => {
|
|
48
|
+
let connected = false;
|
|
49
|
+
let progressDot = '.';
|
|
50
|
+
const exit = makePromiseKit();
|
|
51
|
+
let progressTimer = null;
|
|
52
|
+
|
|
53
|
+
const sendJSON = (ws, obj) => {
|
|
54
|
+
if (ws.readyState !== ws.OPEN) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const body = JSON.stringify(obj);
|
|
58
|
+
console.debug('sendJSON', body.slice(0, 200));
|
|
59
|
+
ws.send(body);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const retryWebsocket = async () => {
|
|
63
|
+
if (!progressTimer) {
|
|
64
|
+
process.stdout.write(`Open CapTP connection to ${wsurl}...`);
|
|
65
|
+
progressDot = '.';
|
|
66
|
+
progressTimer = setInterval(
|
|
67
|
+
() => process.stdout.write(progressDot),
|
|
68
|
+
1000,
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const accessToken = await getAccessToken(
|
|
73
|
+
`${wsurl.hostname}:${getPort(wsurl)}`,
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
// For a WebSocket we need to put the token in the query string.
|
|
77
|
+
assert.typeof(accessToken, 'string');
|
|
78
|
+
const wsWebkey = `${wsurl}?accessToken=${encodeURIComponent(accessToken)}`;
|
|
79
|
+
|
|
80
|
+
const ws = makeWebSocket(wsWebkey, { origin: wsurl.origin });
|
|
81
|
+
ws.on('open', () => {
|
|
82
|
+
const tryOnOpen = async () => {
|
|
83
|
+
connected = true;
|
|
84
|
+
console.debug('Connected to CapTP!');
|
|
85
|
+
// Help disambiguate connections.
|
|
86
|
+
const epoch = now();
|
|
87
|
+
const { dispatch, getBootstrap } = makeCapTP(
|
|
88
|
+
'bundle',
|
|
89
|
+
obj => sendJSON(ws, obj),
|
|
90
|
+
undefined,
|
|
91
|
+
{
|
|
92
|
+
epoch,
|
|
93
|
+
},
|
|
94
|
+
);
|
|
95
|
+
ws.on('message', data => {
|
|
96
|
+
try {
|
|
97
|
+
const obj = JSON.parse(data);
|
|
98
|
+
console.debug('receiving', data.slice(0, 200));
|
|
99
|
+
if (obj.type === 'CTP_ERROR') {
|
|
100
|
+
throw obj.error;
|
|
101
|
+
}
|
|
102
|
+
dispatch(obj);
|
|
103
|
+
} catch (e) {
|
|
104
|
+
console.error('server error processing message', data, e);
|
|
105
|
+
exit.reject(e);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// Wait for the chain to become ready.
|
|
110
|
+
let bootP = getBootstrap();
|
|
111
|
+
let lastUpdateCount;
|
|
112
|
+
let stillLoading = [...need].sort();
|
|
113
|
+
progressDot = 'o';
|
|
114
|
+
for await (const _ of whileTrue(() => stillLoading.length)) {
|
|
115
|
+
// Wait for the notifier to report a new state.
|
|
116
|
+
process.stdout.write(progressDot);
|
|
117
|
+
console.debug('need:', stillLoading.join(', '));
|
|
118
|
+
const update = await E(E.get(bootP).loadingNotifier).getUpdateSince(
|
|
119
|
+
lastUpdateCount,
|
|
120
|
+
);
|
|
121
|
+
lastUpdateCount = update.updateCount;
|
|
122
|
+
|
|
123
|
+
// Skip the deploy if our provides are not needed.
|
|
124
|
+
let needsProvide = !provide.length;
|
|
125
|
+
const notNeeded = [];
|
|
126
|
+
for (const dep of provide) {
|
|
127
|
+
if (update.value.includes(dep)) {
|
|
128
|
+
needsProvide = true;
|
|
129
|
+
} else {
|
|
130
|
+
notNeeded.push(dep);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (!needsProvide) {
|
|
134
|
+
console.info(`Don't need our provides: ${notNeeded.join(', ')}`);
|
|
135
|
+
exit.resolve(0);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const nextLoading = [];
|
|
140
|
+
for (const dep of stillLoading) {
|
|
141
|
+
if (update.value.includes(dep)) {
|
|
142
|
+
// A dependency is still loading.
|
|
143
|
+
nextLoading.push(dep);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
stillLoading = nextLoading;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
clearInterval(progressTimer);
|
|
150
|
+
process.stdout.write('\n');
|
|
151
|
+
console.debug(JSON.stringify(need), 'loaded');
|
|
152
|
+
// Take a new copy, since the chain objects have been added to bootstrap.
|
|
153
|
+
bootP = getBootstrap();
|
|
154
|
+
|
|
155
|
+
await main({ home: bootP });
|
|
156
|
+
|
|
157
|
+
const doneLoading = async () => {
|
|
158
|
+
if (!provide.length) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
console.debug('provide:', provide.join(', '));
|
|
162
|
+
await E(E.get(E.get(bootP).local).http).doneLoading(provide);
|
|
163
|
+
};
|
|
164
|
+
await doneLoading();
|
|
165
|
+
|
|
166
|
+
console.debug('Done!');
|
|
167
|
+
ws.close();
|
|
168
|
+
exit.resolve(0);
|
|
169
|
+
};
|
|
170
|
+
tryOnOpen().catch(e => {
|
|
171
|
+
exit.reject(e);
|
|
172
|
+
ws.close();
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
ws.on('close', (_code, _reason) => {
|
|
176
|
+
console.debug('connection closed');
|
|
177
|
+
if (connected) {
|
|
178
|
+
exit.resolve(1);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
ws.on('error', e => {
|
|
182
|
+
if (e.code === 'ECONNREFUSED' && !connected) {
|
|
183
|
+
// Retry in a little bit.
|
|
184
|
+
setTimeout(() => retryWebsocket().catch(exit.reject), RETRY_DELAY_MS);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
exit.reject(e);
|
|
188
|
+
});
|
|
189
|
+
};
|
|
190
|
+
// Start the retry process.
|
|
191
|
+
return retryWebsocket().then(() => exit.promise);
|
|
192
|
+
};
|
|
47
193
|
|
|
48
194
|
export default async function deployMain(progname, rawArgs, powers, opts) {
|
|
49
|
-
const { anylogger,
|
|
195
|
+
const { anylogger, now, fs } = powers;
|
|
50
196
|
const console = anylogger('agoric:deploy');
|
|
51
197
|
|
|
52
198
|
const allowUnsafePlugins = opts.allowUnsafePlugins;
|
|
53
|
-
|
|
199
|
+
const promptForUnsafePlugins = async () => {
|
|
200
|
+
if (!allowUnsafePlugins) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
54
203
|
const { yesReally } = await inquirer.prompt([
|
|
55
204
|
{
|
|
56
205
|
name: 'yesReally',
|
|
@@ -64,9 +213,10 @@ export default async function deployMain(progname, rawArgs, powers, opts) {
|
|
|
64
213
|
);
|
|
65
214
|
process.exit(1);
|
|
66
215
|
}
|
|
67
|
-
}
|
|
216
|
+
};
|
|
217
|
+
await promptForUnsafePlugins();
|
|
68
218
|
|
|
69
|
-
const
|
|
219
|
+
const scripts = rawArgs.slice(1);
|
|
70
220
|
const provide = opts.provide
|
|
71
221
|
.split(',')
|
|
72
222
|
.map(dep => dep.trim())
|
|
@@ -87,15 +237,6 @@ export default async function deployMain(progname, rawArgs, powers, opts) {
|
|
|
87
237
|
.filter(dep => dep && !provide.includes(dep))
|
|
88
238
|
.sort();
|
|
89
239
|
|
|
90
|
-
const sendJSON = (ws, obj) => {
|
|
91
|
-
if (ws.readyState !== ws.OPEN) {
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
const body = JSON.stringify(obj);
|
|
95
|
-
console.debug('sendJSON', body.slice(0, 200));
|
|
96
|
-
ws.send(body);
|
|
97
|
-
};
|
|
98
|
-
|
|
99
240
|
const match = opts.hostport.match(/^(.*):(\d+)$/);
|
|
100
241
|
const host = match ? match[1] : 'localhost';
|
|
101
242
|
const port = match ? match[2] : '8000';
|
|
@@ -104,25 +245,15 @@ export default async function deployMain(progname, rawArgs, powers, opts) {
|
|
|
104
245
|
? new URL(opts.hostport, 'ws://localhost:8000')
|
|
105
246
|
: new URL(`ws://${host}:${port}`);
|
|
106
247
|
|
|
107
|
-
const myPort =
|
|
108
|
-
wsurl.port || (['https:', 'wss:'].includes(wsurl.protocol) ? '443' : '80');
|
|
109
|
-
|
|
110
248
|
assert.equal(wsurl.pathname, '/', X`${opts.hostport} cannot contain a path`);
|
|
111
249
|
wsurl.pathname = '/private/captp';
|
|
112
250
|
|
|
113
|
-
const exit = makePromiseKit();
|
|
114
|
-
let connected = false;
|
|
115
|
-
process.stdout.write(`Open CapTP connection to ${wsurl}...`);
|
|
116
|
-
let progressDot = '.';
|
|
117
|
-
const progressTimer = setInterval(
|
|
118
|
-
() => process.stdout.write(progressDot),
|
|
119
|
-
1000,
|
|
120
|
-
);
|
|
121
|
-
|
|
122
251
|
const jsonHttpCall = makeJsonHttpClient({ http });
|
|
123
252
|
|
|
124
253
|
const listConnections = async () => {
|
|
125
|
-
const accessToken = await getAccessToken(
|
|
254
|
+
const accessToken = await getAccessToken(
|
|
255
|
+
`${wsurl.hostname}:${getPort(wsurl)}`,
|
|
256
|
+
);
|
|
126
257
|
|
|
127
258
|
const { ok, connections } = await jsonHttpCall({
|
|
128
259
|
hostname: host,
|
|
@@ -181,7 +312,7 @@ export default async function deployMain(progname, rawArgs, powers, opts) {
|
|
|
181
312
|
const { connectionNumber } = await inquirer.prompt({
|
|
182
313
|
name: 'connectionNumber',
|
|
183
314
|
message: 'Please choose a connection to publish to',
|
|
184
|
-
choices: lookup.keys(),
|
|
315
|
+
choices: [...lookup.keys()],
|
|
185
316
|
});
|
|
186
317
|
const connection = lookup.get(connectionNumber);
|
|
187
318
|
console.log({ connection });
|
|
@@ -191,7 +322,6 @@ export default async function deployMain(progname, rawArgs, powers, opts) {
|
|
|
191
322
|
const publishBundleCosmos = makeCosmosBundlePublisher({
|
|
192
323
|
connectWithSigner: SigningStargateClient.connectWithSigner,
|
|
193
324
|
pathResolve: path.resolve,
|
|
194
|
-
writeFile: fs.writeFile,
|
|
195
325
|
readFile: fs.readFile,
|
|
196
326
|
random: Math.random,
|
|
197
327
|
});
|
|
@@ -205,301 +335,45 @@ export default async function deployMain(progname, rawArgs, powers, opts) {
|
|
|
205
335
|
publishBundleHttp,
|
|
206
336
|
});
|
|
207
337
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
const
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
obj => sendJSON(ws, obj),
|
|
224
|
-
undefined,
|
|
225
|
-
{
|
|
226
|
-
epoch,
|
|
227
|
-
},
|
|
228
|
-
);
|
|
229
|
-
ws.on('message', data => {
|
|
230
|
-
try {
|
|
231
|
-
const obj = JSON.parse(data);
|
|
232
|
-
console.debug('receiving', data.slice(0, 200));
|
|
233
|
-
if (obj.type === 'CTP_ERROR') {
|
|
234
|
-
throw obj.error;
|
|
235
|
-
}
|
|
236
|
-
dispatch(obj);
|
|
237
|
-
} catch (e) {
|
|
238
|
-
console.error('server error processing message', data, e);
|
|
239
|
-
exit.reject(e);
|
|
240
|
-
}
|
|
241
|
-
});
|
|
242
|
-
|
|
243
|
-
// Wait for the chain to become ready.
|
|
244
|
-
let bootP = getBootstrap();
|
|
245
|
-
let lastUpdateCount;
|
|
246
|
-
let stillLoading = [...need].sort();
|
|
247
|
-
progressDot = 'o';
|
|
248
|
-
while (stillLoading.length) {
|
|
249
|
-
// Wait for the notifier to report a new state.
|
|
250
|
-
process.stdout.write(progressDot);
|
|
251
|
-
console.debug('need:', stillLoading.join(', '));
|
|
252
|
-
const update = await E(E.get(bootP).loadingNotifier).getUpdateSince(
|
|
253
|
-
lastUpdateCount,
|
|
254
|
-
);
|
|
255
|
-
lastUpdateCount = update.updateCount;
|
|
256
|
-
|
|
257
|
-
// Skip the deploy if our provides are not needed.
|
|
258
|
-
let needsProvide = !provide.length;
|
|
259
|
-
const notNeeded = [];
|
|
260
|
-
for (const dep of provide) {
|
|
261
|
-
if (update.value.includes(dep)) {
|
|
262
|
-
needsProvide = true;
|
|
263
|
-
} else {
|
|
264
|
-
notNeeded.push(dep);
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
if (!needsProvide) {
|
|
268
|
-
console.info(`Don't need our provides: ${notNeeded.join(', ')}`);
|
|
269
|
-
process.exit(0);
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
const nextLoading = [];
|
|
273
|
-
for (const dep of stillLoading) {
|
|
274
|
-
if (update.value.includes(dep)) {
|
|
275
|
-
// A dependency is still loading.
|
|
276
|
-
nextLoading.push(dep);
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
stillLoading = nextLoading;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
clearInterval(progressTimer);
|
|
283
|
-
process.stdout.write('\n');
|
|
284
|
-
console.debug(JSON.stringify(need), 'loaded');
|
|
285
|
-
// Take a new copy, since the chain objects have been added to bootstrap.
|
|
286
|
-
bootP = getBootstrap();
|
|
287
|
-
|
|
288
|
-
const pluginManager = await E.get(E.get(bootP).local).plugin.catch(
|
|
289
|
-
_ => {},
|
|
290
|
-
);
|
|
291
|
-
const pluginDir = await E(pluginManager)
|
|
292
|
-
.getPluginDir()
|
|
293
|
-
.catch(_ => {});
|
|
294
|
-
|
|
295
|
-
if (allowUnsafePlugins && !pluginDir) {
|
|
296
|
-
throw Error(
|
|
297
|
-
`Installing unsafe plugins disabled; no pluginDir detected`,
|
|
298
|
-
);
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
const cache = makeCache(
|
|
302
|
-
E(E(E.get(bootP).wallet).getBridge()).getCacheCoordinator(),
|
|
303
|
-
);
|
|
304
|
-
|
|
305
|
-
let cachedLeader;
|
|
306
|
-
const makeDefaultLeader = async leaderOptions => {
|
|
307
|
-
if (cachedLeader === undefined) {
|
|
308
|
-
const conn = await getDefaultConnection();
|
|
309
|
-
const { type, rpcAddresses } = conn;
|
|
310
|
-
assert.equal(
|
|
311
|
-
type,
|
|
312
|
-
'chain-cosmos-sdk',
|
|
313
|
-
X`${type} doesn't support casting followers`,
|
|
314
|
-
);
|
|
315
|
-
cachedLeader = makeLeaderFromRpcAddresses(
|
|
316
|
-
rpcAddresses,
|
|
317
|
-
leaderOptions,
|
|
318
|
-
);
|
|
319
|
-
}
|
|
320
|
-
return cachedLeader;
|
|
321
|
-
};
|
|
322
|
-
|
|
323
|
-
for (const arg of args) {
|
|
324
|
-
const moduleFile = path.resolve(process.cwd(), arg);
|
|
325
|
-
const pathResolve = (...paths) => {
|
|
326
|
-
const fileName = paths.pop();
|
|
327
|
-
try {
|
|
328
|
-
return require.resolve(fileName, {
|
|
329
|
-
paths: [...paths, path.dirname(moduleFile)],
|
|
330
|
-
});
|
|
331
|
-
} catch (e) {
|
|
332
|
-
return path.resolve(path.dirname(moduleFile), ...paths, fileName);
|
|
333
|
-
}
|
|
334
|
-
};
|
|
335
|
-
console.warn('running', moduleFile);
|
|
336
|
-
|
|
337
|
-
let installUnsafePlugin;
|
|
338
|
-
if (!allowUnsafePlugins) {
|
|
339
|
-
installUnsafePlugin = async (plugin, _opts = undefined) => {
|
|
340
|
-
throw Error(
|
|
341
|
-
`Installing unsafe plugin ${JSON.stringify(
|
|
342
|
-
pathResolve(plugin),
|
|
343
|
-
)} disabled; maybe you meant '--allow-unsafe-plugins'?`,
|
|
344
|
-
);
|
|
345
|
-
};
|
|
346
|
-
} else {
|
|
347
|
-
installUnsafePlugin = async (plugin, pluginOpts = undefined) => {
|
|
348
|
-
try {
|
|
349
|
-
const absPath = pathResolve(plugin);
|
|
350
|
-
const pluginName = absPath.replace(PATH_SEP_RE, '_');
|
|
351
|
-
const pluginFile = path.resolve(pluginDir, pluginName);
|
|
352
|
-
|
|
353
|
-
// Just create a little redirector for that path.
|
|
354
|
-
console.warn(
|
|
355
|
-
`Installing unsafe plugin ${JSON.stringify(absPath)}`,
|
|
356
|
-
);
|
|
357
|
-
const content = `\
|
|
358
|
-
// ${pluginFile}
|
|
359
|
-
// AUTOMATICALLY GENERATED BY ${JSON.stringify(
|
|
360
|
-
[progname, ...rawArgs].join(' '),
|
|
361
|
-
)}
|
|
362
|
-
export { bootPlugin } from ${JSON.stringify(absPath)};
|
|
363
|
-
`;
|
|
364
|
-
await fs.writeFile(pluginFile, content);
|
|
365
|
-
|
|
366
|
-
// Return the bootstrap object for this plugin.
|
|
367
|
-
console.info(`Loading plugin ${JSON.stringify(pluginFile)}`);
|
|
368
|
-
return E.get(E(pluginManager).load(pluginName, pluginOpts))
|
|
369
|
-
.pluginRoot;
|
|
370
|
-
} catch (e) {
|
|
371
|
-
throw Error(
|
|
372
|
-
`Cannot install unsafe plugin: ${(e && e.stack) || e}`,
|
|
373
|
-
);
|
|
374
|
-
}
|
|
375
|
-
};
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
// Use a dynamic import to load the deploy script.
|
|
379
|
-
// It is unconfined.
|
|
380
|
-
|
|
381
|
-
// Use Node.js ESM support if package.json of template says "type":
|
|
382
|
-
// "module".
|
|
383
|
-
const read = async location =>
|
|
384
|
-
fs.readFile(url.fileURLToPath(location));
|
|
385
|
-
const { packageDescriptorText } =
|
|
386
|
-
await readContainingPackageDescriptor(
|
|
387
|
-
read,
|
|
388
|
-
url.pathToFileURL(moduleFile),
|
|
389
|
-
).catch(cause => {
|
|
390
|
-
throw new Error(
|
|
391
|
-
`Expected a package.json beside deploy script ${moduleFile}, ${cause}`,
|
|
392
|
-
{ cause },
|
|
393
|
-
);
|
|
394
|
-
});
|
|
395
|
-
const packageDescriptor = JSON.parse(packageDescriptorText);
|
|
396
|
-
const nativeEsm = packageDescriptor.type === 'module';
|
|
397
|
-
console.log(
|
|
398
|
-
`Deploy script will run with ${
|
|
399
|
-
nativeEsm ? 'Node.js ESM' : 'standardthings/esm emulation'
|
|
400
|
-
}`,
|
|
401
|
-
);
|
|
402
|
-
|
|
403
|
-
const modulePath = pathResolve(moduleFile);
|
|
404
|
-
const mainNS = nativeEsm
|
|
405
|
-
? await import(modulePath)
|
|
406
|
-
: esmRequire(modulePath);
|
|
407
|
-
const main = mainNS.default;
|
|
408
|
-
if (typeof main !== 'function') {
|
|
409
|
-
console.error(
|
|
410
|
-
`${moduleFile} does not have an export default function main`,
|
|
411
|
-
);
|
|
412
|
-
} else {
|
|
413
|
-
await main(bootP, {
|
|
414
|
-
bundleSource: (file, options = undefined) =>
|
|
415
|
-
bundleSource(pathResolve(file), options),
|
|
416
|
-
cache,
|
|
417
|
-
makeDefaultLeader,
|
|
418
|
-
publishBundle,
|
|
419
|
-
listConnections,
|
|
420
|
-
pathResolve,
|
|
421
|
-
installUnsafePlugin,
|
|
422
|
-
/**
|
|
423
|
-
* Recursively look up names in the context of the bootstrap
|
|
424
|
-
* promise, such as:
|
|
425
|
-
*
|
|
426
|
-
* ['agoricNames', 'oracleBrand', 'USD']
|
|
427
|
-
* ['namesByAddress']
|
|
428
|
-
* ['namesByAddress', 'agoric1...']
|
|
429
|
-
* ['namesByAddress', 'agoric1...', 'depositFacet']
|
|
430
|
-
* ['wallet', 'issuer', 'IST']
|
|
431
|
-
*
|
|
432
|
-
* @param {...string[]} namePath
|
|
433
|
-
* @returns {Promise<any>}
|
|
434
|
-
*/
|
|
435
|
-
lookup: (...namePath) => {
|
|
436
|
-
if (namePath.length === 1 && Array.isArray(namePath[0])) {
|
|
437
|
-
// Convert single array argument to a path.
|
|
438
|
-
namePath = namePath[0];
|
|
439
|
-
}
|
|
440
|
-
if (namePath.length === 0) {
|
|
441
|
-
return bootP;
|
|
442
|
-
}
|
|
443
|
-
const [first, ...remaining] = namePath;
|
|
444
|
-
|
|
445
|
-
// The first part of the name path is a property on bootP.
|
|
446
|
-
let nextValue = E.get(bootP)[first];
|
|
447
|
-
if (remaining.length === 0) {
|
|
448
|
-
return nextValue;
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
// Compatibility for agoricdev-8; use `.get` for the next part.
|
|
452
|
-
// TODO: remove when agoricdev-9 is released.
|
|
453
|
-
if (first === 'scratch') {
|
|
454
|
-
const second = remaining.shift();
|
|
455
|
-
const secondValue = E(nextValue).get(second);
|
|
456
|
-
if (remaining.length === 0) {
|
|
457
|
-
return secondValue;
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
// Fall through to the lookup below.
|
|
461
|
-
nextValue = secondValue;
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
// Any remaining paths go through the lookup method of the found
|
|
465
|
-
// object.
|
|
466
|
-
return E(nextValue).lookup(...remaining);
|
|
467
|
-
},
|
|
468
|
-
host,
|
|
469
|
-
port,
|
|
470
|
-
args: opts.scriptArgs,
|
|
471
|
-
});
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
if (provide.length) {
|
|
476
|
-
console.debug('provide:', provide.join(', '));
|
|
477
|
-
await E(E.get(E.get(bootP).local).http).doneLoading(provide);
|
|
478
|
-
}
|
|
338
|
+
let cachedLeader;
|
|
339
|
+
const makeDefaultLeader = async leaderOptions => {
|
|
340
|
+
if (cachedLeader) {
|
|
341
|
+
return cachedLeader;
|
|
342
|
+
}
|
|
343
|
+
const conn = await getDefaultConnection();
|
|
344
|
+
const { type, rpcAddresses } = conn;
|
|
345
|
+
assert.equal(
|
|
346
|
+
type,
|
|
347
|
+
'chain-cosmos-sdk',
|
|
348
|
+
X`${type} doesn't support casting followers`,
|
|
349
|
+
);
|
|
350
|
+
cachedLeader = makeLeaderFromRpcAddresses(rpcAddresses, leaderOptions);
|
|
351
|
+
return cachedLeader;
|
|
352
|
+
};
|
|
479
353
|
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
}
|
|
486
|
-
});
|
|
487
|
-
ws.on('close', (_code, _reason) => {
|
|
488
|
-
console.debug('connection closed');
|
|
489
|
-
if (connected) {
|
|
490
|
-
exit.resolve(1);
|
|
491
|
-
}
|
|
492
|
-
});
|
|
493
|
-
ws.on('error', e => {
|
|
494
|
-
if (e.code === 'ECONNREFUSED' && !connected) {
|
|
495
|
-
// Retry in a little bit.
|
|
496
|
-
setTimeout(retryWebsocket, RETRY_DELAY_MS);
|
|
497
|
-
return;
|
|
498
|
-
}
|
|
499
|
-
exit.reject(e);
|
|
500
|
-
});
|
|
354
|
+
const endowments = {
|
|
355
|
+
now,
|
|
356
|
+
makeDefaultLeader,
|
|
357
|
+
publishBundle,
|
|
358
|
+
listConnections,
|
|
501
359
|
};
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
360
|
+
if (opts.scriptArgs) {
|
|
361
|
+
endowments.scriptArgs = opts.scriptArgs;
|
|
362
|
+
}
|
|
363
|
+
const runScripts = makeScriptLoader(
|
|
364
|
+
scripts,
|
|
365
|
+
{ allowUnsafePlugins, progname, rawArgs, endowments },
|
|
366
|
+
{ fs, console },
|
|
367
|
+
);
|
|
368
|
+
|
|
369
|
+
return connectAndRun(
|
|
370
|
+
wsurl,
|
|
371
|
+
runScripts,
|
|
372
|
+
{ need, provide },
|
|
373
|
+
{
|
|
374
|
+
makeWebSocket: powers.makeWebSocket,
|
|
375
|
+
console,
|
|
376
|
+
now,
|
|
377
|
+
},
|
|
378
|
+
);
|
|
505
379
|
}
|
package/src/entrypoint.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
// @jessie-check
|
|
2
3
|
|
|
3
4
|
/* global process */
|
|
4
5
|
|
|
@@ -37,9 +38,15 @@ main(progname, rawArgs, {
|
|
|
37
38
|
process,
|
|
38
39
|
spawn,
|
|
39
40
|
}).then(
|
|
40
|
-
res =>
|
|
41
|
+
res => {
|
|
42
|
+
if (Number.isSafeInteger(res)) {
|
|
43
|
+
process.exitCode = res;
|
|
44
|
+
}
|
|
45
|
+
},
|
|
41
46
|
rej => {
|
|
42
47
|
log.error(rej);
|
|
43
|
-
process.
|
|
48
|
+
if (!process.exitCode) {
|
|
49
|
+
process.exitCode = 2;
|
|
50
|
+
}
|
|
44
51
|
},
|
|
45
52
|
);
|