agoric 0.22.0-u18.5 → 0.22.0-u18.6

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.
@@ -1,12 +1,19 @@
1
1
  // @ts-check
2
2
  /* eslint-disable func-names */
3
3
  /* eslint-env node */
4
- import { Command } from 'commander';
4
+ import {
5
+ fetchEnvNetworkConfig,
6
+ makeAgoricNames,
7
+ makeVstorageKit,
8
+ storageHelper,
9
+ } from '@agoric/client-utils';
5
10
  import { Offers } from '@agoric/inter-protocol/src/clientSupport.js';
11
+ import { Command } from 'commander';
6
12
  import { asPercent } from '../lib/format.js';
7
- import { makeRpcUtils, storageHelper } from '../lib/rpc.js';
8
13
  import { outputExecuteOfferAction } from '../lib/wallet.js';
9
14
 
15
+ const networkConfig = await fetchEnvNetworkConfig({ env: process.env, fetch });
16
+
10
17
  // Adapted from https://gist.github.com/dckc/8b5b2f16395cb4d7f2ff340e0bc6b610#file-psm-tool
11
18
 
12
19
  /**
@@ -60,13 +67,14 @@ export const makePsmCommand = logger => {
60
67
  );
61
68
 
62
69
  const rpcTools = async () => {
63
- const utils = await makeRpcUtils({ fetch });
70
+ const vsk = await makeVstorageKit({ fetch }, networkConfig);
71
+ const agoricNames = await makeAgoricNames(vsk.fromBoard, vsk.vstorage);
64
72
 
65
73
  const lookupPsmInstance = ([minted, anchor]) => {
66
74
  const name = `psm-${minted}-${anchor}`;
67
- const instance = utils.agoricNames.instance[name];
75
+ const instance = agoricNames.instance[name];
68
76
  if (!instance) {
69
- logger.debug('known instances:', utils.agoricNames.instance);
77
+ logger.debug('known instances:', agoricNames.instance);
70
78
  throw Error(`Unknown instance ${name}`);
71
79
  }
72
80
  return instance;
@@ -77,20 +85,19 @@ export const makePsmCommand = logger => {
77
85
  * @param {[Minted: string, Anchor: string]} pair
78
86
  */
79
87
  const getGovernanceState = async ([Minted, Anchor]) => {
80
- const govContent = await utils.vstorage.readLatest(
88
+ const govContent = await vsk.vstorage.readLatest(
81
89
  `published.psm.${Minted}.${Anchor}.governance`,
82
90
  );
83
91
  assert(govContent, 'no gov content');
84
92
  const { current: governance } = last(
85
- storageHelper.unserializeTxt(govContent, utils.fromBoard),
93
+ storageHelper.unserializeTxt(govContent, vsk.fromBoard),
86
94
  );
87
- const { [`psm.${Minted}.${Anchor}`]: instance } =
88
- utils.agoricNames.instance;
95
+ const { [`psm.${Minted}.${Anchor}`]: instance } = agoricNames.instance;
89
96
 
90
97
  return { instance, governance };
91
98
  };
92
99
 
93
- return { ...utils, lookupPsmInstance, getGovernanceState };
100
+ return { ...vsk, agoricNames, lookupPsmInstance, getGovernanceState };
94
101
  };
95
102
 
96
103
  psm
@@ -1,11 +1,17 @@
1
1
  // @ts-check
2
2
  /* eslint-disable func-names */
3
3
  /* eslint-env node */
4
+ import {
5
+ fetchEnvNetworkConfig,
6
+ makeAgoricNames,
7
+ makeVstorageKit,
8
+ } from '@agoric/client-utils';
4
9
  import { Offers } from '@agoric/inter-protocol/src/clientSupport.js';
5
10
  import { Command } from 'commander';
6
- import { makeRpcUtils } from '../lib/rpc.js';
7
11
  import { outputActionAndHint } from '../lib/wallet.js';
8
12
 
13
+ const networkConfig = await fetchEnvNetworkConfig({ env: process.env, fetch });
14
+
9
15
  /**
10
16
  * @param {import('anylogger').Logger} _logger
11
17
  * @param {*} io
@@ -29,7 +35,8 @@ export const makeReserveCommand = (_logger, io = {}) => {
29
35
  * }} opts
30
36
  */
31
37
  async ({ collateralBrand, ...opts }) => {
32
- const { agoricNames } = await makeRpcUtils({ fetch });
38
+ const vsk = makeVstorageKit({ fetch }, networkConfig);
39
+ const agoricNames = await makeAgoricNames(vsk.fromBoard, vsk.vstorage);
33
40
 
34
41
  const offer = Offers.reserve.AddCollateral(agoricNames, {
35
42
  collateralBrandKey: collateralBrand,
@@ -63,7 +70,8 @@ export const makeReserveCommand = (_logger, io = {}) => {
63
70
  1,
64
71
  )
65
72
  .action(async function (opts) {
66
- const { agoricNames } = await makeRpcUtils({ fetch });
73
+ const vsk = makeVstorageKit({ fetch }, networkConfig);
74
+ const agoricNames = await makeAgoricNames(vsk.fromBoard, vsk.vstorage);
67
75
 
68
76
  const reserveInstance = agoricNames.instance.reserve;
69
77
  assert(reserveInstance, 'missing reserve in names');
@@ -1,11 +1,11 @@
1
1
  // @ts-check
2
2
  /* eslint-env node */
3
+ import { fetchEnvNetworkConfig, makeWalletUtils } from '@agoric/client-utils';
3
4
  import { Fail } from '@endo/errors';
4
5
  import { CommanderError } from 'commander';
5
6
  import { normalizeAddressWithOptions } from '../lib/chain.js';
6
7
  import { bigintReplacer } from '../lib/format.js';
7
- import { getNetworkConfig } from '../lib/rpc.js';
8
- import { makeWalletUtils, sendAction } from '../lib/wallet.js';
8
+ import { sendAction } from '../lib/wallet.js';
9
9
 
10
10
  /**
11
11
  * Make commands for testing.
@@ -38,8 +38,8 @@ export const makeTestCommand = (
38
38
  try {
39
39
  // XXX pass fetch to getNetworkConfig() explicitly
40
40
  // await null above makes this await safe
41
- const networkConfig = await getNetworkConfig(env);
42
- return makeWalletUtils({ fetch, execFileSync, delay }, networkConfig);
41
+ const networkConfig = await fetchEnvNetworkConfig({ env, fetch });
42
+ return makeWalletUtils({ fetch, delay }, networkConfig);
43
43
  } catch (err) {
44
44
  // CommanderError is a class constructor, and so
45
45
  // must be invoked with `new`.
@@ -1,15 +1,21 @@
1
1
  // @ts-check
2
2
  /* eslint-disable func-names */
3
3
  /* eslint-env node */
4
- import { Command } from 'commander';
4
+ import {
5
+ fetchEnvNetworkConfig,
6
+ makeAgoricNames,
7
+ makeVstorageKit,
8
+ } from '@agoric/client-utils';
5
9
  import {
6
10
  lookupOfferIdForVault,
7
11
  Offers,
8
12
  } from '@agoric/inter-protocol/src/clientSupport.js';
13
+ import { Command } from 'commander';
9
14
  import { normalizeAddressWithOptions } from '../lib/chain.js';
10
- import { makeRpcUtils } from '../lib/rpc.js';
11
15
  import { getCurrent, outputExecuteOfferAction } from '../lib/wallet.js';
12
16
 
17
+ const networkConfig = await fetchEnvNetworkConfig({ env: process.env, fetch });
18
+
13
19
  /**
14
20
  * @param {import('anylogger').Logger} logger
15
21
  */
@@ -36,10 +42,10 @@ export const makeVaultsCommand = logger => {
36
42
  normalizeAddress,
37
43
  )
38
44
  .action(async function (opts) {
39
- const { readLatestHead } = await makeRpcUtils({ fetch });
45
+ const { readPublished } = await makeVstorageKit({ fetch }, networkConfig);
40
46
 
41
47
  const current = await getCurrent(opts.from, {
42
- readLatestHead,
48
+ readPublished,
43
49
  });
44
50
 
45
51
  const vaultStoragePaths = current.offerToPublicSubscriberPaths.map(
@@ -61,7 +67,8 @@ export const makeVaultsCommand = logger => {
61
67
  .option('--collateralBrand <string>', 'Collateral brand key', 'ATOM')
62
68
  .action(async function (opts) {
63
69
  logger.warn('running with options', opts);
64
- const { agoricNames } = await makeRpcUtils({ fetch });
70
+ const vsk = makeVstorageKit({ fetch }, networkConfig);
71
+ const agoricNames = await makeAgoricNames(vsk.fromBoard, vsk.vstorage);
65
72
 
66
73
  const offer = Offers.vaults.OpenVault(agoricNames, {
67
74
  giveCollateral: opts.giveCollateral,
@@ -96,11 +103,15 @@ export const makeVaultsCommand = logger => {
96
103
  .requiredOption('--vaultId <string>', 'Key of vault (e.g. vault1)')
97
104
  .action(async function (opts) {
98
105
  logger.warn('running with options', opts);
99
- const { agoricNames, readLatestHead } = await makeRpcUtils({ fetch });
106
+ const { readPublished, ...vsk } = makeVstorageKit(
107
+ { fetch },
108
+ networkConfig,
109
+ );
110
+ const agoricNames = await makeAgoricNames(vsk.fromBoard, vsk.vstorage);
100
111
 
101
112
  const previousOfferId = await lookupOfferIdForVault(
102
113
  opts.vaultId,
103
- getCurrent(opts.from, { readLatestHead }),
114
+ getCurrent(opts.from, { readPublished }),
104
115
  );
105
116
 
106
117
  const offer = Offers.vaults.AdjustBalances(
@@ -137,11 +148,15 @@ export const makeVaultsCommand = logger => {
137
148
  )
138
149
  .action(async function (opts) {
139
150
  logger.warn('running with options', opts);
140
- const { agoricNames, readLatestHead } = await makeRpcUtils({ fetch });
151
+ const { readPublished, ...vsk } = makeVstorageKit(
152
+ { fetch },
153
+ networkConfig,
154
+ );
155
+ const agoricNames = await makeAgoricNames(vsk.fromBoard, vsk.vstorage);
141
156
 
142
157
  const previousOfferId = await lookupOfferIdForVault(
143
158
  opts.vaultId,
144
- getCurrent(opts.from, { readLatestHead }),
159
+ getCurrent(opts.from, { readPublished }),
145
160
  );
146
161
 
147
162
  const offer = Offers.vaults.CloseVault(
@@ -8,11 +8,14 @@ import {
8
8
  makeLeader,
9
9
  makeLeaderFromRpcAddresses,
10
10
  } from '@agoric/casting';
11
+ import {
12
+ makeVstorageKit,
13
+ fetchEnvNetworkConfig,
14
+ makeAgoricNames,
15
+ } from '@agoric/client-utils';
16
+ import { execFileSync } from 'child_process';
11
17
  import fs from 'fs';
12
18
  import util from 'util';
13
- import { execFileSync } from 'child_process';
14
- import { fmtRecordOfLines, summarize } from '../lib/format.js';
15
- import { makeRpcUtils, networkConfig } from '../lib/rpc.js';
16
19
 
17
20
  import { makeLeaderOptions } from '../lib/casting.js';
18
21
  import {
@@ -20,8 +23,15 @@ import {
20
23
  fetchSwingsetParams,
21
24
  normalizeAddressWithOptions,
22
25
  } from '../lib/chain.js';
26
+ import {
27
+ fmtRecordOfLines,
28
+ parseFiniteNumber,
29
+ summarize,
30
+ } from '../lib/format.js';
23
31
  import { coalesceWalletState, getCurrent } from '../lib/wallet.js';
24
32
 
33
+ const networkConfig = await fetchEnvNetworkConfig({ env: process.env, fetch });
34
+
25
35
  const SLEEP_SECONDS = 3;
26
36
 
27
37
  /**
@@ -102,7 +112,7 @@ export const makeWalletCommand = async command => {
102
112
  .action(async function (opts) {
103
113
  const offerStr = fs.readFileSync(opts.file).toString();
104
114
 
105
- const { unserializer } = await makeRpcUtils({ fetch });
115
+ const { unserializer } = await makeVstorageKit({ fetch }, networkConfig);
106
116
 
107
117
  const offerObj = unserializer.fromCapData(JSON.parse(offerStr));
108
118
  console.log(offerObj);
@@ -117,7 +127,7 @@ export const makeWalletCommand = async command => {
117
127
  .action(async function (opts) {
118
128
  const offerStr = fs.readFileSync(opts.offer).toString();
119
129
 
120
- const { unserializer } = await makeRpcUtils({ fetch });
130
+ const { unserializer } = await makeVstorageKit({ fetch }, networkConfig);
121
131
 
122
132
  const offerObj = unserializer.fromCapData(JSON.parse(offerStr));
123
133
  console.log(offerObj.offer.id);
@@ -132,30 +142,69 @@ export const makeWalletCommand = async command => {
132
142
  )
133
143
  .requiredOption('--offer [filename]', 'path to file with prepared offer')
134
144
  .option('--dry-run', 'spit out the command instead of running it')
145
+ .option('--gas', 'gas limit; "auto" [default] to calculate automatically')
146
+ .option(
147
+ '--gas-adjustment',
148
+ 'factor by which to multiply the --gas=auto calculation result [default 1.2]',
149
+ )
150
+ .option('--verbose', 'print command output')
135
151
  .action(function (opts) {
136
- /** @typedef {{ from: string, offer: string, dryRun: boolean }} Opts */
152
+ /**
153
+ * @typedef {{
154
+ * from: string,
155
+ * offer: string,
156
+ * dryRun: boolean,
157
+ * gas: string,
158
+ * gasAdjustment: string,
159
+ * verbose: boolean,
160
+ * }} Opts
161
+ */
137
162
  const {
138
163
  dryRun,
139
164
  from,
165
+ gas = 'auto',
166
+ gasAdjustment = '1.2',
140
167
  offer,
141
168
  home,
169
+ verbose,
142
170
  keyringBackend: backend,
143
171
  } = /** @type {SharedTxOptions & Opts} */ ({ ...wallet.opts(), ...opts });
144
172
 
145
173
  const offerBody = fs.readFileSync(offer).toString();
146
- execSwingsetTransaction(['wallet-action', '--allow-spend', offerBody], {
147
- from,
148
- dryRun,
149
- keyring: { home, backend },
150
- ...networkConfig,
151
- });
174
+ const out = execSwingsetTransaction(
175
+ ['wallet-action', '--allow-spend', offerBody, '-ojson', '-bblock'],
176
+ {
177
+ ...networkConfig,
178
+ keyring: { home, backend },
179
+ from,
180
+ gas:
181
+ gas === 'auto'
182
+ ? ['auto', parseFiniteNumber(gasAdjustment)]
183
+ : parseFiniteNumber(gas),
184
+ dryRun,
185
+ verbose,
186
+ },
187
+ );
188
+
189
+ // see sendAction in {@link ../lib/wallet.js}
190
+ if (dryRun || !verbose) return;
191
+ try {
192
+ const tx = JSON.parse(/** @type {string} */ (out));
193
+ if (tx.code !== 0) {
194
+ console.error('failed to send tx', tx);
195
+ }
196
+ console.log(tx);
197
+ } catch (err) {
198
+ console.error('unexpected output', JSON.stringify(out));
199
+ throw err;
200
+ }
152
201
  });
153
202
 
154
203
  wallet
155
204
  .command('list')
156
205
  .description('list all wallets in vstorage')
157
206
  .action(async function () {
158
- const { vstorage } = await makeRpcUtils({ fetch });
207
+ const { vstorage } = await makeVstorageKit({ fetch }, networkConfig);
159
208
  const wallets = await vstorage.keys('published.wallet');
160
209
  process.stdout.write(wallets.join('\n'));
161
210
  });
@@ -169,23 +218,24 @@ export const makeWalletCommand = async command => {
169
218
  normalizeAddress,
170
219
  )
171
220
  .action(async function (opts) {
172
- const { agoricNames, unserializer, readLatestHead } = await makeRpcUtils({
173
- fetch,
174
- });
221
+ const { readPublished, unserializer, ...vsk } = makeVstorageKit(
222
+ { fetch },
223
+ networkConfig,
224
+ );
225
+ const agoricNames = await makeAgoricNames(vsk.fromBoard, vsk.vstorage);
175
226
 
176
227
  const leader = makeLeader(networkConfig.rpcAddrs[0]);
177
228
  const follower = await makeFollower(
178
229
  `:published.wallet.${opts.from}`,
179
230
  leader,
180
231
  {
181
- // @ts-expect-error xxx
182
232
  unserializer,
183
233
  },
184
234
  );
185
235
 
186
236
  const coalesced = await coalesceWalletState(follower);
187
237
 
188
- const current = await getCurrent(opts.from, { readLatestHead });
238
+ const current = await getCurrent(opts.from, { readPublished });
189
239
 
190
240
  console.warn(
191
241
  'got coalesced',
package/src/cosmos.js CHANGED
@@ -50,7 +50,7 @@ export default async function cosmosMain(progname, rawArgs, powers, opts) {
50
50
  },
51
51
  );
52
52
  // Ensure the build doesn't mess up stdout.
53
- ps.childProcess.stdout.pipe(process.stderr);
53
+ ps.childProcess.stdout?.pipe(process.stderr);
54
54
  return ps;
55
55
  }
56
56
  throw e;
package/src/helpers.js CHANGED
@@ -3,6 +3,9 @@
3
3
 
4
4
  /** @import { ChildProcess } from 'child_process' */
5
5
 
6
+ // Backwards compatibility
7
+ export { fetchEnvNetworkConfig as getNetworkConfig } from '@agoric/client-utils';
8
+
6
9
  export const getSDKBinaries = ({
7
10
  jsPfx = '../..',
8
11
  goPfx = `${jsPfx}/../golang`,
@@ -40,12 +43,12 @@ export const makePspawn = ({
40
43
  *
41
44
  * @param {string} cmd command name to run
42
45
  * @param {Array<string>} cargs arguments to the command
43
- * @param {object} param2
44
- * @param {string} [param2.cwd]
45
- * @param {string | [string, string, string]} [param2.stdio] standard IO
46
+ * @param {object} [opts]
47
+ * @param {string} [opts.cwd]
48
+ * @param {string | [string, string, string]} [opts.stdio] standard IO
46
49
  * specification
47
- * @param {Record<string, string | undefined>} [param2.env] environment
48
- * @param {boolean} [param2.detached] whether the child process should be detached
50
+ * @param {Record<string, string | undefined>} [opts.env] environment
51
+ * @param {boolean} [opts.detached] whether the child process should be detached
49
52
  * @returns {Promise<number> & { childProcess: ChildProcess }}} promise for
50
53
  * exit status. The return result has a `childProcess` property to obtain
51
54
  * control over the running process
package/src/install.js CHANGED
@@ -37,7 +37,7 @@ export default async function installMain(progname, rawArgs, powers, opts) {
37
37
  stdio: ['inherit', 'pipe', 'inherit'],
38
38
  });
39
39
  const stdout = [];
40
- p.childProcess.stdout.on('data', out => stdout.push(out));
40
+ p.childProcess.stdout?.on('data', out => stdout.push(out));
41
41
  await p;
42
42
  const d = JSON.parse(Buffer.concat(stdout).toString('utf-8'));
43
43
  for (const [name, { location }] of Object.entries(d)) {
@@ -49,7 +49,7 @@ export default async function installMain(progname, rawArgs, powers, opts) {
49
49
  let subdirs;
50
50
  const workTrees = ['.'];
51
51
  let sdkWorktree;
52
- /** @type {Map<string, string>} */
52
+ /** @type {Map<string, string | null>} */
53
53
  const sdkPackageToPath = new Map();
54
54
  const linkFolder = path.resolve(`_agstate/yarn-links`);
55
55
  const linkFlags = [];
@@ -131,7 +131,6 @@ export default async function installMain(progname, rawArgs, powers, opts) {
131
131
  // Ensure we update the package.json before exiting.
132
132
  const updatePackageJson = async () => {
133
133
  // Don't update on exit anymore.
134
- // eslint-disable-next-line no-use-before-define
135
134
  process.off('beforeExit', updatePackageJsonOnExit);
136
135
  log.info(`updating ${pjson}`);
137
136
  await fs.writeFile(
@@ -170,7 +169,7 @@ export default async function installMain(progname, rawArgs, powers, opts) {
170
169
  .then(results => {
171
170
  // After all have settled, throw any errors.
172
171
  const failures = results.filter(
173
- ({ status }) => status !== 'fulfilled',
172
+ result => result.status !== 'fulfilled',
174
173
  );
175
174
  if (failures.length) {
176
175
  throw AggregateError(
@@ -284,6 +283,10 @@ export default async function installMain(progname, rawArgs, powers, opts) {
284
283
  // Create symlinks to the SDK packages.
285
284
  await Promise.all(
286
285
  [...sdkPackageToPath.entries()].map(async ([pjName, dir]) => {
286
+ if (typeof dir !== 'string') {
287
+ throw Error(`unexpected incomplete package mapping: ${pjName}`);
288
+ }
289
+
287
290
  const SUBOPTIMAL = false;
288
291
  await null;
289
292
  if (SUBOPTIMAL) {
@@ -301,7 +304,7 @@ export default async function installMain(progname, rawArgs, powers, opts) {
301
304
  log('linking', linkName);
302
305
  return fs
303
306
  .mkdir(linkDir, { recursive: true })
304
- .then(_ => fs.symlink(path.relative(linkDir, dir), linkName));
307
+ .then(() => fs.symlink(path.relative(linkDir, dir), linkName));
305
308
  }),
306
309
  );
307
310
 
package/src/lib/chain.js CHANGED
@@ -3,6 +3,10 @@
3
3
  import { normalizeBech32 } from '@cosmjs/encoding';
4
4
  import { execFileSync as execFileSyncAmbient } from 'child_process';
5
5
 
6
+ /**
7
+ * @import {MinimalNetworkConfig} from '@agoric/client-utils';
8
+ */
9
+
6
10
  const agdBinary = 'agd';
7
11
 
8
12
  /**
@@ -34,11 +38,42 @@ export const normalizeAddressWithOptions = (
34
38
  };
35
39
  harden(normalizeAddressWithOptions);
36
40
 
41
+ /** @typedef {number | 'auto' | ['auto', adjustment?: number | undefined]} GasLimit */
42
+
43
+ /**
44
+ * @param {GasLimit} limit
45
+ * @returns {string[]}
46
+ */
47
+ const makeGasOpts = limit => {
48
+ if (Number.isFinite(limit) || limit === 'auto') {
49
+ return [`--gas=${limit}`];
50
+ }
51
+ if (Array.isArray(limit) && limit.length >= 1 && limit[0] === 'auto') {
52
+ const gasOpts = ['--gas=auto'];
53
+ if (limit.length > 1) {
54
+ const [adjustment, ...rest] = limit.slice(1);
55
+ const adjustmentIsValid =
56
+ adjustment === undefined ||
57
+ (Number.isFinite(adjustment) && Number(adjustment) > 0);
58
+ if (rest.length !== 0 || !adjustmentIsValid) {
59
+ throw Error('invalid gas input');
60
+ }
61
+ if (adjustment !== undefined) {
62
+ gasOpts.push(`--gas-adjustment=${adjustment}`);
63
+ }
64
+ }
65
+ return gasOpts;
66
+ }
67
+
68
+ throw Error('invalid gas input');
69
+ };
70
+
37
71
  /**
38
72
  * @param {ReadonlyArray<string>} swingsetArgs
39
- * @param {import('./rpc.js').MinimalNetworkConfig & {
73
+ * @param {MinimalNetworkConfig & {
40
74
  * from: string,
41
75
  * fees?: string,
76
+ * gas?: GasLimit,
42
77
  * dryRun?: boolean,
43
78
  * verbose?: boolean,
44
79
  * keyring?: {home?: string, backend: string}
@@ -50,6 +85,7 @@ export const execSwingsetTransaction = (swingsetArgs, opts) => {
50
85
  const {
51
86
  from,
52
87
  fees,
88
+ gas = ['auto', 1.2],
53
89
  dryRun = false,
54
90
  verbose = true,
55
91
  keyring = undefined,
@@ -67,6 +103,7 @@ export const execSwingsetTransaction = (swingsetArgs, opts) => {
67
103
  homeOpt,
68
104
  backendOpt,
69
105
  feeOpt,
106
+ makeGasOpts(gas),
70
107
  [`--from=${from}`, 'tx', 'swingset'],
71
108
  swingsetArgs,
72
109
  );
@@ -78,7 +115,7 @@ export const execSwingsetTransaction = (swingsetArgs, opts) => {
78
115
  stdout.write('\n');
79
116
  } else {
80
117
  const yesCmd = cmd.concat(['--yes']);
81
- if (verbose) console.log('Executing ', yesCmd);
118
+ if (verbose) console.log('Executing ', agdBinary, yesCmd);
82
119
  const out = execFileSync(agdBinary, yesCmd, { encoding: 'utf-8' });
83
120
 
84
121
  // agd puts this diagnostic on stdout rather than stderr :-/
@@ -94,7 +131,7 @@ harden(execSwingsetTransaction);
94
131
 
95
132
  /**
96
133
  *
97
- * @param {import('./rpc.js').MinimalNetworkConfig} net
134
+ * @param {MinimalNetworkConfig} net
98
135
  */
99
136
  // TODO fetch by HTTP instead of shelling out https://github.com/Agoric/agoric-sdk/issues/9200
100
137
  export const fetchSwingsetParams = net => {
@@ -114,7 +151,7 @@ export const fetchSwingsetParams = net => {
114
151
  harden(fetchSwingsetParams);
115
152
 
116
153
  /**
117
- * @param {import('./rpc.js').MinimalNetworkConfig & {
154
+ * @param {MinimalNetworkConfig & {
118
155
  * execFileSync: typeof import('child_process').execFileSync,
119
156
  * delay: (ms: number) => Promise<void>,
120
157
  * period?: number,
@@ -154,7 +191,7 @@ export const pollBlocks = opts => async lookup => {
154
191
 
155
192
  /**
156
193
  * @param {string} txhash
157
- * @param {import('./rpc.js').MinimalNetworkConfig & {
194
+ * @param {MinimalNetworkConfig & {
158
195
  * execFileSync: typeof import('child_process').execFileSync,
159
196
  * delay: (ms: number) => Promise<void>,
160
197
  * period?: number,
package/src/lib/format.js CHANGED
@@ -1,23 +1,21 @@
1
- // @ts-check
2
-
3
1
  import { Fail, q } from '@endo/errors';
4
2
  import { makeBoardRemote } from '@agoric/vats/tools/board-utils.js';
5
3
 
6
- /** @import {BoardRemote} from '@agoric/vats/tools/board-utils.js' */
7
- /** @import {VBankAssetDetail} from '@agoric/vats/tools/board-utils.js'; */
4
+ /**
5
+ * @import {Amount, Brand} from '@agoric/ertp'
6
+ * @import {AgoricNamesRemotes, BoardRemote, VBankAssetDetail} from '@agoric/vats/tools/board-utils.js';
7
+ */
8
8
 
9
+ // TODO Move to packages/internal.
9
10
  /**
10
- * Like @endo/nat but coerces
11
+ * Parses the input and returns either a finite number or NaN.
11
12
  *
12
- * @param {string} str
13
- * @returns {bigint}
13
+ * @param {string} input
14
+ * @returns {number}
14
15
  */
15
- export const Natural = str => {
16
- const b = BigInt(str);
17
- if (b < 0) {
18
- throw RangeError(`${b} is negative`);
19
- }
20
- return b;
16
+ export const parseFiniteNumber = input => {
17
+ const result = /[0-9]/.test(input || '') ? Number(input) : NaN;
18
+ return Number.isFinite(result) ? result : NaN;
21
19
  };
22
20
 
23
21
  /**
@@ -102,14 +100,15 @@ export const purseBalanceTuples = (purses, assets) => {
102
100
  */
103
101
  export const fmtRecordOfLines = record => {
104
102
  const { stringify } = JSON;
103
+ /** @type {Array<[string, string[]]>} */
105
104
  const groups = Object.entries(record).map(([key, items]) => [
106
105
  key,
107
106
  items.map(item => ` ${stringify(item)}`),
108
107
  ]);
109
- const lineEntries = groups.map(
110
- // @ts-expect-error ???
111
- ([key, lines]) => ` ${stringify(key)}: [\n${lines.join(',\n')}\n ]`,
112
- );
108
+ const lineEntries = groups.map(([key, lines]) => {
109
+ const linesStr = lines.length === 0 ? `[]` : `[\n${lines.join(',\n')}\n ]`;
110
+ return ` ${stringify(key)}: ${linesStr}`;
111
+ });
113
112
  return `{\n${lineEntries.join(',\n')}\n}`;
114
113
  };
115
114
 
@@ -117,7 +116,7 @@ export const fmtRecordOfLines = record => {
117
116
  * Summarize the offerStatuses of the state as user-facing informative tuples
118
117
  *
119
118
  * @param {import('@agoric/smart-wallet/src/utils.js').CoalescedWalletState} state
120
- * @param {import('@agoric/vats/tools/board-utils.js').AgoricNamesRemotes} agoricNames
119
+ * @param {AgoricNamesRemotes} agoricNames
121
120
  */
122
121
  export const offerStatusTuples = (state, agoricNames) => {
123
122
  const { offerStatuses } = state;
@@ -174,7 +173,7 @@ export const offerStatusTuples = (state, agoricNames) => {
174
173
  /**
175
174
  * @param {import('@agoric/smart-wallet/src/smartWallet.js').CurrentWalletRecord} current
176
175
  * @param {ReturnType<import('@agoric/smart-wallet/src/utils.js').makeWalletStateCoalescer>['state']} coalesced
177
- * @param {import('@agoric/vats/tools/board-utils.js').AgoricNamesRemotes} agoricNames
176
+ * @param {AgoricNamesRemotes} agoricNames
178
177
  */
179
178
  export const summarize = (current, coalesced, agoricNames) => {
180
179
  return {
@@ -0,0 +1,7 @@
1
+ /** @file Utility library for use in other packages */
2
+
3
+ export * from './bundles.js';
4
+ export * from './casting.js';
5
+ export * from './chain.js';
6
+ export * from './format.js';
7
+ export * from './wallet.js';