agoric 0.22.0-upgrade-16-dev-0df76a7.0 → 0.22.0-upgrade-17-dev-a61cdab.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agoric",
3
- "version": "0.22.0-upgrade-16-dev-0df76a7.0+0df76a7",
3
+ "version": "0.22.0-upgrade-17-dev-a61cdab.0+a61cdab",
4
4
  "description": "Manage the Agoric Javascript smart contract platform",
5
5
  "type": "module",
6
6
  "main": "src/main.js",
@@ -29,46 +29,46 @@
29
29
  "lint:eslint": "eslint ."
30
30
  },
31
31
  "devDependencies": {
32
- "@agoric/cosmic-swingset": "0.42.0-upgrade-16-dev-0df76a7.0+0df76a7",
33
- "@agoric/deploy-script-support": "0.10.4-upgrade-16-dev-0df76a7.0+0df76a7",
32
+ "@agoric/cosmic-swingset": "0.42.0-upgrade-17-dev-a61cdab.0+a61cdab",
33
+ "@agoric/deploy-script-support": "0.10.4-upgrade-17-dev-a61cdab.0+a61cdab",
34
34
  "ava": "^5.3.0",
35
35
  "c8": "^9.1.0",
36
36
  "dd-trace": "^4.11.1"
37
37
  },
38
38
  "dependencies": {
39
- "@agoric/access-token": "0.4.22-upgrade-16-dev-0df76a7.0+0df76a7",
40
- "@agoric/assert": "0.6.1-upgrade-16-dev-0df76a7.0+0df76a7",
41
- "@agoric/cache": "0.3.3-upgrade-16-dev-0df76a7.0+0df76a7",
42
- "@agoric/casting": "0.4.3-upgrade-16-dev-0df76a7.0+0df76a7",
43
- "@agoric/cosmic-proto": "0.4.1-upgrade-16-dev-0df76a7.0+0df76a7",
44
- "@agoric/ertp": "0.16.3-upgrade-16-dev-0df76a7.0+0df76a7",
45
- "@agoric/governance": "0.10.4-upgrade-16-dev-0df76a7.0+0df76a7",
46
- "@agoric/inter-protocol": "0.17.0-upgrade-16-dev-0df76a7.0+0df76a7",
47
- "@agoric/internal": "0.4.0-upgrade-16-dev-0df76a7.0+0df76a7",
48
- "@agoric/network": "0.2.0-upgrade-16-dev-0df76a7.0+0df76a7",
49
- "@agoric/smart-wallet": "0.5.4-upgrade-16-dev-0df76a7.0+0df76a7",
50
- "@agoric/store": "0.9.3-upgrade-16-dev-0df76a7.0+0df76a7",
51
- "@agoric/swingset-vat": "0.33.0-upgrade-16-dev-0df76a7.0+0df76a7",
52
- "@agoric/vats": "0.16.0-upgrade-16-dev-0df76a7.0+0df76a7",
53
- "@agoric/zoe": "0.26.3-upgrade-16-dev-0df76a7.0+0df76a7",
54
- "@agoric/zone": "0.3.0-upgrade-16-dev-0df76a7.0+0df76a7",
39
+ "@agoric/access-token": "0.4.22-upgrade-17-dev-a61cdab.0+a61cdab",
40
+ "@agoric/cache": "0.3.3-upgrade-17-dev-a61cdab.0+a61cdab",
41
+ "@agoric/casting": "0.4.3-upgrade-17-dev-a61cdab.0+a61cdab",
42
+ "@agoric/cosmic-proto": "0.5.0-upgrade-17-dev-a61cdab.0+a61cdab",
43
+ "@agoric/ertp": "0.16.3-upgrade-17-dev-a61cdab.0+a61cdab",
44
+ "@agoric/governance": "0.10.4-upgrade-17-dev-a61cdab.0+a61cdab",
45
+ "@agoric/inter-protocol": "0.17.0-upgrade-17-dev-a61cdab.0+a61cdab",
46
+ "@agoric/internal": "0.4.0-upgrade-17-dev-a61cdab.0+a61cdab",
47
+ "@agoric/network": "0.2.0-upgrade-17-dev-a61cdab.0+a61cdab",
48
+ "@agoric/smart-wallet": "0.5.4-upgrade-17-dev-a61cdab.0+a61cdab",
49
+ "@agoric/store": "0.9.3-upgrade-17-dev-a61cdab.0+a61cdab",
50
+ "@agoric/swingset-vat": "0.33.0-upgrade-17-dev-a61cdab.0+a61cdab",
51
+ "@agoric/vats": "0.16.0-upgrade-17-dev-a61cdab.0+a61cdab",
52
+ "@agoric/zoe": "0.26.3-upgrade-17-dev-a61cdab.0+a61cdab",
53
+ "@agoric/zone": "0.3.0-upgrade-17-dev-a61cdab.0+a61cdab",
55
54
  "@confio/relayer": "^0.11.3",
56
55
  "@cosmjs/crypto": "^0.32.3",
57
56
  "@cosmjs/encoding": "^0.32.3",
58
57
  "@cosmjs/math": "^0.32.3",
59
58
  "@cosmjs/proto-signing": "^0.32.3",
60
59
  "@cosmjs/stargate": "^0.32.3",
61
- "@endo/bundle-source": "^3.2.3",
62
- "@endo/captp": "^4.2.0",
63
- "@endo/compartment-mapper": "^1.1.5",
64
- "@endo/env-options": "^1.1.4",
65
- "@endo/far": "^1.1.2",
66
- "@endo/init": "^1.1.2",
67
- "@endo/marshal": "^1.5.0",
68
- "@endo/nat": "^5.0.7",
69
- "@endo/patterns": "^1.4.0",
70
- "@endo/promise-kit": "^1.1.2",
71
- "@endo/zip": "^1.0.5",
60
+ "@endo/bundle-source": "^3.4.0",
61
+ "@endo/captp": "^4.3.0",
62
+ "@endo/compartment-mapper": "^1.2.2",
63
+ "@endo/env-options": "^1.1.6",
64
+ "@endo/errors": "^1.2.5",
65
+ "@endo/far": "^1.1.5",
66
+ "@endo/init": "^1.1.4",
67
+ "@endo/marshal": "^1.5.3",
68
+ "@endo/nat": "^5.0.10",
69
+ "@endo/patterns": "^1.4.3",
70
+ "@endo/promise-kit": "^1.1.5",
71
+ "@endo/zip": "^1.0.7",
72
72
  "@iarna/toml": "^2.2.3",
73
73
  "anylogger": "^0.21.0",
74
74
  "chalk": "^5.2.0",
@@ -99,7 +99,7 @@
99
99
  "workerThreads": false
100
100
  },
101
101
  "typeCoverage": {
102
- "atLeast": 76.99
102
+ "atLeast": 77.44
103
103
  },
104
- "gitHead": "0df76a71058eda04cdc75a54fb4312d286f323a3"
104
+ "gitHead": "a61cdabb23bd2c846e003dee7326018a7462a929"
105
105
  }
@@ -1,11 +1,10 @@
1
1
  // @ts-check
2
2
 
3
3
  import { InvalidArgumentError } from 'commander';
4
+ import { Fail } from '@endo/errors';
4
5
  import { makeRpcUtils } from '../lib/rpc.js';
5
6
  import { outputActionAndHint } from '../lib/wallet.js';
6
7
 
7
- const { Fail } = assert;
8
-
9
8
  /**
10
9
  * @import {ParamTypesMap, ParamTypesMapFromRecord} from '@agoric/governance/src/contractGovernance/typedParamManager.js'
11
10
  * @import {ParamValueForType} from '@agoric/governance/src/types.js'
@@ -131,6 +130,8 @@ export const makeAuctionCommand = (
131
130
  };
132
131
 
133
132
  if (Object.keys(params).length === 0) {
133
+ // InvalidArgumentError is a class constructor, and so
134
+ // must be invoked with `new`.
134
135
  throw new InvalidArgumentError(`no parameters given`);
135
136
  }
136
137
 
@@ -73,6 +73,8 @@ export const makeGovCommand = (_logger, io = {}) => {
73
73
  const done = found.filter(it => it.instanceName === instanceName);
74
74
  if (done.length > 0) {
75
75
  console.warn(`invitation to ${instanceName} already accepted`, done);
76
+ // CommanderError is a class constructor, and so
77
+ // must be invoked with `new`.
76
78
  throw new CommanderError(1, 'EALREADY', `already accepted`);
77
79
  }
78
80
  };
@@ -330,6 +332,8 @@ export const makeGovCommand = (_logger, io = {}) => {
330
332
  const info = await readLatestHead(
331
333
  `published.committees.${opts.pathname}.latestQuestion`,
332
334
  ).catch(err => {
335
+ // CommanderError is a class constructor, and so
336
+ // must be invoked with `new`.
333
337
  throw new CommanderError(1, 'VSTORAGE_FAILURE', err.message);
334
338
  });
335
339
 
@@ -346,6 +350,8 @@ export const makeGovCommand = (_logger, io = {}) => {
346
350
  const votingRight = cont.find(it => it.instanceName === opts.instance);
347
351
  if (!votingRight) {
348
352
  console.debug('continuing ids', cont, 'for', current);
353
+ // CommanderError is a class constructor, and so
354
+ // must be invoked with `new`.
349
355
  throw new CommanderError(
350
356
  1,
351
357
  'NO_INVITATION',
@@ -218,6 +218,8 @@ export const makeInterCommand = (
218
218
  try {
219
219
  return rawExec(file, args, ...opts);
220
220
  } catch (err) {
221
+ // InvalidArgumentError is a class constructor, and so
222
+ // must be invoked with `new`.
221
223
  throw new InvalidArgumentError(
222
224
  `${err.message}: is ${file} in your $PATH?`,
223
225
  );
@@ -239,6 +241,8 @@ export const makeInterCommand = (
239
241
  const networkConfig = await getNetworkConfig(env);
240
242
  return makeWalletUtils({ fetch, execFileSync, delay }, networkConfig);
241
243
  } catch (err) {
244
+ // CommanderError is a class constructor, and so
245
+ // must be invoked with `new`.
242
246
  throw new CommanderError(1, 'RPC_FAIL', err.message);
243
247
  }
244
248
  };
@@ -431,6 +435,8 @@ inter auction status
431
435
  const parsePercent = v => {
432
436
  const p = Number(v);
433
437
  if (!(p >= -100 && p <= 100)) {
438
+ // InvalidArgumentError is a class constructor, and so
439
+ // must be invoked with `new`.
434
440
  throw new InvalidArgumentError('must be between -100 and 100');
435
441
  }
436
442
  return p / 100;
@@ -498,6 +504,8 @@ inter auction status
498
504
  const current = await getCurrent(from, { readLatestHead });
499
505
  const liveIds = current.liveOffers.map(([i, _s]) => i);
500
506
  if (!liveIds.includes(id)) {
507
+ // InvalidArgumentError is a class constructor, and so
508
+ // must be invoked with `new`.
501
509
  throw new InvalidArgumentError(
502
510
  `${id} not in live offer ids: ${liveIds}`,
503
511
  );
@@ -1,9 +1,9 @@
1
1
  // @ts-check
2
2
  /* eslint-disable func-names */
3
3
  /* global fetch, setTimeout, process */
4
- import { Fail } from '@agoric/assert';
5
- import { Offers } from '@agoric/inter-protocol/src/clientSupport.js';
4
+ import { Fail } from '@endo/errors';
6
5
  import { Nat } from '@endo/nat';
6
+ import { Offers } from '@agoric/inter-protocol/src/clientSupport.js';
7
7
  import { Command } from 'commander';
8
8
  import * as cp from 'child_process';
9
9
  import { inspect } from 'util';
@@ -26,6 +26,8 @@ const COSMOS_UNIT = 1_000_000n;
26
26
  const scaleDecimals = num => BigInt(num * Number(COSMOS_UNIT));
27
27
 
28
28
  /**
29
+ * Prints JSON output to stdout and diagnostic info (like logs) to stderr
30
+ *
29
31
  * @param {import('anylogger').Logger} logger
30
32
  * @param {{
31
33
  * delay?: (ms: number) => Promise<void>,
@@ -271,14 +273,13 @@ export const makeOracleCommand = (logger, io = {}) => {
271
273
  );
272
274
  const unitPrice = scaleDecimals(price);
273
275
 
274
- console.error(`${pair[0]}-${pair[1]}_price_feed: before setPrice`);
276
+ const feedPath = `published.priceFeed.${pair[0]}-${pair[1]}_price_feed`;
275
277
 
276
278
  const readPrice = () =>
277
279
  /** @type {Promise<PriceDescription>} */ (
278
- readLatestHead(
279
- `published.priceFeed.${pair[0]}-${pair[1]}_price_feed`,
280
- ).catch(err => {
281
- console.warn(`cannot get ${pair[0]}-${pair[1]}_price_feed`, err);
280
+ readLatestHead(feedPath).catch(() => {
281
+ const viewer = `https://vstorage.agoric.net/#${networkConfig.rpcAddrs[0]}|published,published.priceFeed|${feedPath}`;
282
+ console.warn(`no existing price data; see ${viewer}`);
282
283
  return undefined;
283
284
  })
284
285
  );
@@ -297,43 +298,61 @@ export const makeOracleCommand = (logger, io = {}) => {
297
298
  show(fmtFeed(before));
298
299
  }
299
300
 
300
- console.error(
301
- 'Choose lead oracle operator order based on latestRound...',
302
- );
303
301
  const keyOrder = keys.map(normalizeAddress);
304
- const latestRoundP = readLatestHead(
305
- `published.priceFeed.${pair[0]}-${pair[1]}_price_feed.latestRound`,
306
- );
307
- await Promise.race([
308
- delay(5000),
309
- latestRoundP.then(round => {
310
- // @ts-expect-error XXX get type from contract
311
- const { roundId, startedAt, startedBy } = round;
312
- show({
313
- startedAt: fmtSecs(startedAt.absValue),
314
- roundId,
315
- startedBy,
316
- });
317
- if (startedBy === keyOrder[0]) {
318
- keyOrder.reverse();
319
- }
320
- }),
321
- ]).catch(err => {
322
- console.warn(err);
323
- });
302
+ if (before) {
303
+ console.error(
304
+ 'Choose lead oracle operator order based on latestRound...',
305
+ );
324
306
 
325
- const instance = lookupPriceAggregatorInstance(pair);
307
+ const latestRoundP =
308
+ /** @type {Promise<{roundId: number, startedAt: import('@agoric/time').TimestampRecord, startedBy: string}>} */ (
309
+ readLatestHead(
310
+ `published.priceFeed.${pair[0]}-${pair[1]}_price_feed.latestRound`,
311
+ )
312
+ );
313
+ await Promise.race([
314
+ delay(5000),
315
+ latestRoundP.then(round => {
316
+ const { roundId, startedAt, startedBy } = round;
317
+ show({
318
+ startedAt: fmtSecs(startedAt.absValue),
319
+ roundId,
320
+ startedBy,
321
+ });
322
+ if (startedBy === keyOrder[0]) {
323
+ keyOrder.reverse();
324
+ }
325
+ }),
326
+ ]).catch(err => {
327
+ console.warn(err);
328
+ });
329
+ }
326
330
 
327
- console.error('pushPrice from each:', keyOrder);
331
+ const instance = lookupPriceAggregatorInstance(pair);
332
+ const adminOfferIds = {};
328
333
  for await (const from of keyOrder) {
329
- const oracleAdminAcceptOfferId = await findOracleCap(
334
+ adminOfferIds[from] = await findOracleCap(
330
335
  instance,
331
336
  from,
332
337
  readLatestHead,
333
338
  );
334
- if (!oracleAdminAcceptOfferId) {
335
- throw Error(`no oracle invitation found: ${from}`);
339
+ if (!adminOfferIds[from]) {
340
+ console.error(
341
+ `Failed to find an offer accepting oracle invitation for ${from}. Accept and try again:`,
342
+ );
343
+ console.error(
344
+ ` agops oracle accept > accept.json; agoric wallet send --from ${from} --offer accept.json`,
345
+ );
336
346
  }
347
+ }
348
+ assert(
349
+ Object.values(adminOfferIds).every(x => x),
350
+ 'Missing oracle admin offer ids',
351
+ );
352
+
353
+ console.error('pushPrice from each:', keyOrder);
354
+ for await (const from of keyOrder) {
355
+ const oracleAdminAcceptOfferId = adminOfferIds[from];
337
356
  show({ from, oracleAdminAcceptOfferId });
338
357
  const offerId = `pushPrice-${Date.now()}`;
339
358
  const offer = Offers.fluxAggregator.PushPrice(
@@ -1,6 +1,6 @@
1
1
  // @ts-check
2
2
  /* global process */
3
- import { Fail } from '@agoric/assert';
3
+ import { Fail } from '@endo/errors';
4
4
  import { CommanderError } from 'commander';
5
5
  import { normalizeAddressWithOptions } from '../lib/chain.js';
6
6
  import { bigintReplacer } from '../lib/format.js';
@@ -41,6 +41,8 @@ export const makeTestCommand = (
41
41
  const networkConfig = await getNetworkConfig(env);
42
42
  return makeWalletUtils({ fetch, execFileSync, delay }, networkConfig);
43
43
  } catch (err) {
44
+ // CommanderError is a class constructor, and so
45
+ // must be invoked with `new`.
44
46
  throw new CommanderError(1, 'RPC_FAIL', err.message);
45
47
  }
46
48
  };
package/src/deploy.js CHANGED
@@ -1,8 +1,9 @@
1
1
  // @ts-check
2
2
  /* global process setTimeout setInterval clearInterval */
3
3
 
4
- import { E, makeCapTP } from '@endo/captp';
4
+ import { X } from '@endo/errors';
5
5
  import { makePromiseKit } from '@endo/promise-kit';
6
+ import { E, makeCapTP } from '@endo/captp';
6
7
  import { makeLeaderFromRpcAddresses } from '@agoric/casting';
7
8
  import path from 'path';
8
9
  import http from 'http';
@@ -20,8 +21,6 @@ import {
20
21
  import { makeJsonHttpClient } from './json-http-client-node.js';
21
22
  import { makeScriptLoader } from './scripts.js';
22
23
 
23
- const { details: X } = assert;
24
-
25
24
  // note: CapTP has its own HandledPromise instantiation, and the contract
26
25
  // must use the same one that CapTP uses. We achieve this by not bundling
27
26
  // captp, and doing a (non-isolated) dynamic import of the deploy script
package/src/helpers.js CHANGED
@@ -45,6 +45,7 @@ export const makePspawn = ({
45
45
  * @param {string | [string, string, string]} [param2.stdio] standard IO
46
46
  * specification
47
47
  * @param {Record<string, string | undefined>} [param2.env] environment
48
+ * @param {boolean} [param2.detached] whether the child process should be detached
48
49
  * @returns {Promise<number> & { childProcess: ChildProcess }}} promise for
49
50
  * exit status. The return result has a `childProcess` property to obtain
50
51
  * control over the running process
package/src/init.js CHANGED
@@ -1,8 +1,6 @@
1
1
  import chalk from 'chalk';
2
2
  import { makePspawn } from './helpers.js';
3
3
 
4
- /// <reference types="@endo/captp/src/types.js" />
5
-
6
4
  // Use either an absolute template URL, or find it relative to DAPP_URL_BASE.
7
5
  const gitURL = (relativeOrAbsoluteURL, base) => {
8
6
  const url = new URL(relativeOrAbsoluteURL, base);
@@ -11,7 +11,8 @@ import { ZipReader } from '@endo/zip';
11
11
  /** @import {Bundle} from '@agoric/swingset-vat'; */
12
12
  /** @import {CoreEvalPlan} from '@agoric/deploy-script-support/src/writeCoreEvalParts.js' */
13
13
 
14
- const PACKAGE_NAME_RE = /(?<packageName>.*-v[\d.]+)\//;
14
+ // exported for testing
15
+ export const PACKAGE_NAME_RE = /^(?:@[^/]+\/)?[^/]+/;
15
16
 
16
17
  /**
17
18
  * @typedef {{ name: string, label: string, location: string, modules: Record<string, {compartment: string, module: string}>}} Compartment
@@ -27,7 +28,7 @@ const PACKAGE_NAME_RE = /(?<packageName>.*-v[\d.]+)\//;
27
28
  /** @param {Bundle} bundleObj*/
28
29
  export const extractBundleInfo = async bundleObj => {
29
30
  if (bundleObj.moduleFormat !== 'endoZipBase64') {
30
- throw new Error('only endoZipBase64 is supported');
31
+ throw Error('only endoZipBase64 is supported');
31
32
  }
32
33
 
33
34
  const contents = Buffer.from(bundleObj.endoZipBase64, 'base64');
@@ -70,7 +71,7 @@ export const statBundle = async bundleFilename => {
70
71
  if (filename === 'compartment-map.json') {
71
72
  continue;
72
73
  }
73
- const { packageName } = filename.match(PACKAGE_NAME_RE)?.groups ?? {};
74
+ const packageName = filename.match(PACKAGE_NAME_RE)?.[0];
74
75
  assert(packageName, `invalid filename ${filename}`);
75
76
  byPackage[packageName] ||= 0;
76
77
  byPackage[packageName] += size;
package/src/lib/format.js CHANGED
@@ -1,5 +1,6 @@
1
1
  // @ts-check
2
2
 
3
+ import { Fail, q } from '@endo/errors';
3
4
  import { makeBoardRemote } from '@agoric/vats/tools/board-utils.js';
4
5
 
5
6
  /** @import {BoardRemote} from '@agoric/vats/tools/board-utils.js' */
@@ -71,8 +72,6 @@ export const asPercent = ratio => {
71
72
  return (100 * Number(numerator.value)) / Number(denominator.value);
72
73
  };
73
74
 
74
- const { Fail, quote: q } = assert;
75
-
76
75
  const isObject = x => typeof x === 'object' && x !== null;
77
76
 
78
77
  /**
package/src/lib/rpc.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // @ts-check
2
2
  /* global Buffer, fetch, process */
3
3
 
4
- import { NonNullish } from '@agoric/assert';
4
+ import { NonNullish } from '@agoric/internal';
5
5
  import {
6
6
  boardSlottingMarshaller,
7
7
  makeBoardRemote,
package/src/lib/wallet.js CHANGED
@@ -1,6 +1,7 @@
1
1
  // @ts-check
2
2
  /* global process */
3
3
 
4
+ import { Fail } from '@endo/errors';
4
5
  import { iterateReverse } from '@agoric/casting';
5
6
  import { makeWalletStateCoalescer } from '@agoric/smart-wallet/src/utils.js';
6
7
  import { execSwingsetTransaction, pollBlocks, pollTx } from './chain.js';
@@ -9,7 +10,6 @@ import { boardSlottingMarshaller, makeRpcUtils } from './rpc.js';
9
10
  /** @import {CurrentWalletRecord} from '@agoric/smart-wallet/src/smartWallet.js' */
10
11
  /** @import {AgoricNamesRemotes} from '@agoric/vats/tools/board-utils.js' */
11
12
 
12
- const { Fail } = assert;
13
13
  const marshaller = boardSlottingMarshaller();
14
14
 
15
15
  /** @type {CurrentWalletRecord} */
@@ -33,7 +33,7 @@ export const getCurrent = async (addr, { readLatestHead }) => {
33
33
  await readLatestHead(`published.wallet.${addr}.current`)
34
34
  );
35
35
  if (current === undefined) {
36
- throw new Error(`undefined current node for ${addr}`);
36
+ throw Error(`undefined current node for ${addr}`);
37
37
  }
38
38
 
39
39
  // Repair a type misunderstanding seen in the wild.
package/src/main.js CHANGED
@@ -1,12 +1,12 @@
1
1
  /* global process */
2
- import { assert, details as X } from '@agoric/assert';
3
- import {
4
- DEFAULT_JITTER_SECONDS,
5
- DEFAULT_KEEP_POLLING_SECONDS,
6
- } from '@agoric/casting';
7
2
  import { Command } from 'commander';
8
3
  import path from 'path';
9
4
  import url from 'url';
5
+ import { assert, X } from '@endo/errors';
6
+ import {
7
+ DEFAULT_KEEP_POLLING_SECONDS,
8
+ DEFAULT_JITTER_SECONDS,
9
+ } from '@agoric/casting';
10
10
  import { makeWalletCommand } from './commands/wallet.js';
11
11
  import cosmosMain from './cosmos.js';
12
12
  import deployMain from './deploy.js';
package/src/open.js CHANGED
@@ -1,10 +1,8 @@
1
1
  /* global process setInterval clearInterval */
2
2
  import opener from 'opener';
3
-
3
+ import { assert, X } from '@endo/errors';
4
4
  import { getAccessToken } from '@agoric/access-token';
5
5
 
6
- import { assert, details as X } from '@agoric/assert';
7
-
8
6
  export default async function walletMain(_progname, _rawArgs, powers, opts) {
9
7
  const { anylogger } = powers;
10
8
  const console = anylogger('agoric:wallet');
package/src/publish.js CHANGED
@@ -1,6 +1,7 @@
1
1
  // @ts-check
2
2
  /// <reference types="ses" />
3
3
 
4
+ import { X, q, Fail } from '@endo/errors';
4
5
  import { E } from '@endo/far';
5
6
 
6
7
  import {
@@ -14,7 +15,6 @@ import { defaultRegistryTypes } from '@cosmjs/stargate';
14
15
  import { stringToPath } from '@cosmjs/crypto';
15
16
  import { Decimal } from '@cosmjs/math';
16
17
  import { fromBech32 } from '@cosmjs/encoding';
17
-
18
18
  import { MsgInstallBundle } from '@agoric/cosmic-proto/swingset/msgs.js';
19
19
 
20
20
  // https://github.com/Agoric/agoric-sdk/blob/master/golang/cosmos/daemon/main.go
@@ -83,8 +83,6 @@ const registry = new Registry([
83
83
  * @typedef {SourceBundle | HashBundle} Bundle
84
84
  */
85
85
 
86
- const { details: X, quote: q, Fail } = assert;
87
-
88
86
  /**
89
87
  * @template T
90
88
  * @param {Array<T>} array
package/src/scripts.js CHANGED
@@ -161,8 +161,17 @@ export { bootPlugin } from ${JSON.stringify(absPath)};
161
161
 
162
162
  const allEndowments = harden({
163
163
  home: bootP,
164
- bundleSource: (file, options = undefined) =>
165
- bundleSource(pathResolve(file), options),
164
+ /**
165
+ * @template {import('@endo/bundle-source').ModuleFormat} ModuleFormat
166
+ * @param {string} file
167
+ * @param {import('@endo/bundle-source').BundleOptions<ModuleFormat>} options
168
+ * @returns {Promise<import('@endo/bundle-source').BundleSourceResult<ModuleFormat>>}
169
+ */
170
+ bundleSource: (file, options = {}) =>
171
+ bundleSource(pathResolve(file), {
172
+ elideComments: true,
173
+ ...options,
174
+ }),
166
175
  ...endowments,
167
176
  pathResolve,
168
177
  installUnsafePlugin,
@@ -2,7 +2,7 @@
2
2
  // prettier-ignore
3
3
  export default [
4
4
  "@agoric/access-token",
5
- "@agoric/assert",
5
+ "@agoric/async-flow",
6
6
  "@agoric/base-zone",
7
7
  "@agoric/benchmark",
8
8
  "@agoric/boot",
@@ -24,6 +24,7 @@ export default [
24
24
  "@agoric/kmarshal",
25
25
  "@agoric/network",
26
26
  "@agoric/notifier",
27
+ "@agoric/orchestration",
27
28
  "@agoric/pegasus",
28
29
  "@agoric/smart-wallet",
29
30
  "@agoric/solo",
@@ -1,5 +1,5 @@
1
1
  import { basename } from 'path';
2
- import { Fail } from '@agoric/assert';
2
+ import { Fail } from '@endo/errors';
3
3
  import {
4
4
  finishCosmosApp,
5
5
  finishTendermintConfig,
@@ -1,4 +1,5 @@
1
- /* global process setTimeout setInterval clearInterval */
1
+ // @ts-check
2
+ /* global process setTimeout setInterval clearInterval Buffer */
2
3
 
3
4
  import fs from 'fs';
4
5
  import path from 'path';
@@ -10,7 +11,13 @@ import { spawn } from 'child_process';
10
11
 
11
12
  import { makePspawn } from '../src/helpers.js';
12
13
 
13
- const TIMEOUT_SECONDS = 3 * 60;
14
+ const RETRY_BLOCKHEIGHT_SECONDS = 3;
15
+ const SOCKET_TIMEOUT_SECONDS = 2;
16
+
17
+ // TODO: Set this to `true` when `agoric install $DISTTAG` properly updates the
18
+ // getting-started workflow's dependencies to current `@endo/*` and Agoric SDK
19
+ // from the local registry.
20
+ const AGORIC_INSTALL_DISTTAG = false;
14
21
 
15
22
  const dirname = new URL('./', import.meta.url).pathname;
16
23
 
@@ -18,23 +25,59 @@ const dirname = new URL('./', import.meta.url).pathname;
18
25
 
19
26
  // Note that we currently only test:
20
27
  // agoric init dapp-foo
21
- // yarn install
28
+ // yarn install (or agoric install $DISTTAG)
22
29
  // yarn start:docker
23
30
  // yarn start:contract
24
31
  // yarn start:ui
25
32
 
33
+ /**
34
+ * @param {string} url
35
+ * @returns {Promise<bigint>}
36
+ */
37
+ const getLatestBlockHeight = url =>
38
+ new Promise((resolve, reject) => {
39
+ const req = request(url, res => {
40
+ if (!res) {
41
+ reject(Error('no result'));
42
+ return;
43
+ }
44
+ const bodyChunks = [];
45
+ res
46
+ .on('data', chunk => bodyChunks.push(chunk))
47
+ .on('end', () => {
48
+ const body = Buffer.concat(bodyChunks).toString('utf8');
49
+ const { statusCode = 0 } = res;
50
+ if (statusCode >= 200 && statusCode < 300) {
51
+ const { result: { sync_info: sync = {} } = {} } = JSON.parse(body);
52
+ if (sync.catching_up === false) {
53
+ resolve(BigInt(sync.latest_block_height));
54
+ return;
55
+ }
56
+ }
57
+ reject(Error(`Cannot get block height: ${statusCode} ${body}`));
58
+ });
59
+ });
60
+ req.setTimeout(SOCKET_TIMEOUT_SECONDS * 1_000);
61
+ req.on('error', reject);
62
+ req.end();
63
+ });
64
+
26
65
  export const gettingStartedWorkflowTest = async (t, options = {}) => {
27
- const { init: initOptions = [] } = options;
66
+ const { init: initOptions = [], install: installOptions = [] } = options;
28
67
  const pspawn = makePspawn({ spawn });
29
68
 
30
69
  // Kill an entire process group.
31
70
  const pkill = (cp, signal = 'SIGINT') => process.kill(-cp.pid, signal);
32
71
 
72
+ /** @param {Parameters<typeof pspawn>} args */
33
73
  function pspawnStdout(...args) {
34
74
  const ps = pspawn(...args);
35
- ps.childProcess.stdout.on('data', chunk => {
36
- process.stdout.write(chunk);
37
- });
75
+ const { stdout } = ps.childProcess;
76
+ if (stdout) {
77
+ stdout.on('data', chunk => {
78
+ process.stdout.write(chunk);
79
+ });
80
+ }
38
81
  // ps.childProcess.unref();
39
82
  return ps;
40
83
  }
@@ -107,17 +150,51 @@ export const gettingStartedWorkflowTest = async (t, options = {}) => {
107
150
  );
108
151
  process.chdir('dapp-foo');
109
152
 
110
- // ==============
111
- // yarn install
112
- t.is(await yarn(['install']), 0, 'yarn install works');
153
+ if (AGORIC_INSTALL_DISTTAG && process.env.AGORIC_INSTALL_OPTIONS) {
154
+ // ==============
155
+ // agoric install $DISTTAG
156
+ const opts = JSON.parse(process.env.AGORIC_INSTALL_OPTIONS);
157
+ installOptions.push(...opts);
158
+ t.is(
159
+ await myMain(['install', ...installOptions]),
160
+ 0,
161
+ 'agoric install works',
162
+ );
163
+ } else {
164
+ // ==============
165
+ // yarn install
166
+ t.is(await yarn(['install', ...installOptions]), 0, 'yarn install works');
167
+ }
113
168
 
114
169
  // ==============
115
170
  // yarn start:docker
116
171
  t.is(await yarn(['start:docker']), 0, 'yarn start:docker works');
117
172
 
118
- // XXX: use abci_info endpoint to get block height
119
- // sleep to let contract start
120
- await new Promise(resolve => setTimeout(resolve, TIMEOUT_SECONDS));
173
+ // ==============
174
+ // wait for the chain to start
175
+ let lastKnownBlockHeight = 0n;
176
+ for (;;) {
177
+ try {
178
+ const currentHeight = await getLatestBlockHeight(
179
+ 'http://localhost:26657/status',
180
+ );
181
+ if (currentHeight > lastKnownBlockHeight) {
182
+ const earlierHeight = lastKnownBlockHeight;
183
+ lastKnownBlockHeight = currentHeight;
184
+ if (earlierHeight > 0n && currentHeight > earlierHeight) {
185
+ // We've had at least one block produced.
186
+ break;
187
+ }
188
+ }
189
+ } catch (e) {
190
+ console.error((e && e.message) || e);
191
+ }
192
+
193
+ // Wait a bit and try again.
194
+ await new Promise(resolve =>
195
+ setTimeout(resolve, RETRY_BLOCKHEIGHT_SECONDS * 1_000),
196
+ );
197
+ }
121
198
 
122
199
  // ==============
123
200
  // yarn start:contract
@@ -145,9 +222,9 @@ export const gettingStartedWorkflowTest = async (t, options = {}) => {
145
222
  const req = request('http://localhost:5173/', _res => {
146
223
  resolve('listening');
147
224
  });
148
- req.setTimeout(2000);
225
+ req.setTimeout(SOCKET_TIMEOUT_SECONDS * 1_000);
149
226
  req.on('error', err => {
150
- if (err.code !== 'ECONNREFUSED') {
227
+ if (!('code' in err) || err.code !== 'ECONNREFUSED') {
151
228
  resolve(`Cannot connect to UI server: ${err}`);
152
229
  }
153
230
  });