agoric 0.22.0-upgrade-14-dev-c8f9e7b.0 → 0.22.0-upgrade-16-dev-07b0130.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-14-dev-c8f9e7b.0+c8f9e7b",
3
+ "version": "0.22.0-upgrade-16-dev-07b0130.0+07b0130",
4
4
  "description": "Manage the Agoric Javascript smart contract platform",
5
5
  "type": "module",
6
6
  "main": "src/main.js",
@@ -25,44 +25,50 @@
25
25
  "integration-test": "ava --config .ava-integration-test.config.js",
26
26
  "lint-fix": "yarn lint:eslint --fix",
27
27
  "lint": "run-s --continue-on-error lint:*",
28
- "lint:types": "tsc -p jsconfig.json",
28
+ "lint:types": "tsc",
29
29
  "lint:eslint": "eslint ."
30
30
  },
31
31
  "devDependencies": {
32
- "@agoric/deploy-script-support": "0.10.4-upgrade-14-dev-c8f9e7b.0+c8f9e7b",
33
- "ava": "^5.2.0",
34
- "c8": "^7.13.0",
35
- "dd-trace": "^3.3.0"
32
+ "@agoric/cosmic-swingset": "0.42.0-upgrade-16-dev-07b0130.0+07b0130",
33
+ "@agoric/deploy-script-support": "0.10.4-upgrade-16-dev-07b0130.0+07b0130",
34
+ "ava": "^5.3.0",
35
+ "c8": "^9.1.0",
36
+ "dd-trace": "^4.11.1"
36
37
  },
37
38
  "dependencies": {
38
- "@agoric/access-token": "0.4.22-upgrade-14-dev-c8f9e7b.0+c8f9e7b",
39
- "@agoric/assert": "0.6.1-upgrade-14-dev-c8f9e7b.0+c8f9e7b",
40
- "@agoric/cache": "0.3.3-upgrade-14-dev-c8f9e7b.0+c8f9e7b",
41
- "@agoric/casting": "0.4.3-upgrade-14-dev-c8f9e7b.0+c8f9e7b",
42
- "@agoric/cosmic-proto": "0.3.1-upgrade-14-dev-c8f9e7b.0+c8f9e7b",
43
- "@agoric/ertp": "0.16.3-upgrade-14-dev-c8f9e7b.0+c8f9e7b",
44
- "@agoric/inter-protocol": "0.16.2-upgrade-14-dev-c8f9e7b.0+c8f9e7b",
45
- "@agoric/internal": "0.4.0-upgrade-14-dev-c8f9e7b.0+c8f9e7b",
46
- "@agoric/smart-wallet": "0.5.4-upgrade-14-dev-c8f9e7b.0+c8f9e7b",
47
- "@agoric/store": "0.9.3-upgrade-14-dev-c8f9e7b.0+c8f9e7b",
48
- "@agoric/swingset-vat": "0.32.3-upgrade-14-dev-c8f9e7b.0+c8f9e7b",
49
- "@agoric/vats": "0.15.2-upgrade-14-dev-c8f9e7b.0+c8f9e7b",
50
- "@agoric/zoe": "0.26.3-upgrade-14-dev-c8f9e7b.0+c8f9e7b",
51
- "@agoric/zone": "0.2.3-upgrade-14-dev-c8f9e7b.0+c8f9e7b",
52
- "@confio/relayer": "^0.9.0",
53
- "@cosmjs/crypto": "^0.30.1",
54
- "@cosmjs/encoding": "^0.30.1",
55
- "@cosmjs/math": "^0.30.1",
56
- "@cosmjs/proto-signing": "^0.30.1",
57
- "@cosmjs/stargate": "^0.30.1",
58
- "@endo/bundle-source": "2.5.2-upstream-rollup",
59
- "@endo/captp": "3.1.1",
60
- "@endo/compartment-mapper": "0.8.4",
61
- "@endo/far": "0.2.18",
62
- "@endo/init": "0.5.56",
63
- "@endo/marshal": "0.8.5",
64
- "@endo/nat": "4.1.27",
65
- "@endo/promise-kit": "0.2.56",
39
+ "@agoric/access-token": "0.4.22-upgrade-16-dev-07b0130.0+07b0130",
40
+ "@agoric/assert": "0.6.1-upgrade-16-dev-07b0130.0+07b0130",
41
+ "@agoric/cache": "0.3.3-upgrade-16-dev-07b0130.0+07b0130",
42
+ "@agoric/casting": "0.4.3-upgrade-16-dev-07b0130.0+07b0130",
43
+ "@agoric/cosmic-proto": "0.4.1-upgrade-16-dev-07b0130.0+07b0130",
44
+ "@agoric/ertp": "0.16.3-upgrade-16-dev-07b0130.0+07b0130",
45
+ "@agoric/governance": "0.10.4-upgrade-16-dev-07b0130.0+07b0130",
46
+ "@agoric/inter-protocol": "0.17.0-upgrade-16-dev-07b0130.0+07b0130",
47
+ "@agoric/internal": "0.4.0-upgrade-16-dev-07b0130.0+07b0130",
48
+ "@agoric/network": "0.2.0-upgrade-16-dev-07b0130.0+07b0130",
49
+ "@agoric/smart-wallet": "0.5.4-upgrade-16-dev-07b0130.0+07b0130",
50
+ "@agoric/store": "0.9.3-upgrade-16-dev-07b0130.0+07b0130",
51
+ "@agoric/swingset-vat": "0.33.0-upgrade-16-dev-07b0130.0+07b0130",
52
+ "@agoric/vats": "0.16.0-upgrade-16-dev-07b0130.0+07b0130",
53
+ "@agoric/zoe": "0.26.3-upgrade-16-dev-07b0130.0+07b0130",
54
+ "@agoric/zone": "0.3.0-upgrade-16-dev-07b0130.0+07b0130",
55
+ "@confio/relayer": "^0.11.3",
56
+ "@cosmjs/crypto": "^0.32.3",
57
+ "@cosmjs/encoding": "^0.32.3",
58
+ "@cosmjs/math": "^0.32.3",
59
+ "@cosmjs/proto-signing": "^0.32.3",
60
+ "@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",
66
72
  "@iarna/toml": "^2.2.3",
67
73
  "anylogger": "^0.21.0",
68
74
  "chalk": "^5.2.0",
@@ -87,10 +93,13 @@
87
93
  "homepage": "https://github.com/Agoric/agoric-sdk#readme",
88
94
  "ava": {
89
95
  "files": [
90
- "test/**/test-*.js"
96
+ "test/**/*.test.*"
91
97
  ],
92
98
  "timeout": "2m",
93
99
  "workerThreads": false
94
100
  },
95
- "gitHead": "c8f9e7be1645e0be23f47de197409a7d4874add5"
101
+ "typeCoverage": {
102
+ "atLeast": 76.99
103
+ },
104
+ "gitHead": "07b01308eaccca903919d495aded620c9849efc7"
96
105
  }
@@ -1,31 +1,45 @@
1
- /* global process */
1
+ import {
2
+ getEnvironmentOption,
3
+ getEnvironmentOptionsList,
4
+ } from '@endo/env-options';
2
5
  import anylogger from 'anylogger';
3
6
  import chalk from 'chalk';
4
7
 
5
- // Turn on debugging output with DEBUG=agoric
6
- const { DEBUG } = process.env;
7
- let selectedLevel = 'info';
8
- if (DEBUG === undefined) {
9
- selectedLevel = 'log';
10
- } else if (DEBUG.includes('agoric')) {
11
- selectedLevel = 'debug';
8
+ const DEBUG_LIST = getEnvironmentOptionsList('DEBUG');
9
+
10
+ // Turn on debugging output with DEBUG=agoric or DEBUG=agoric:${level}
11
+ let selectedLevel =
12
+ DEBUG_LIST.length || getEnvironmentOption('DEBUG', 'unset') === 'unset'
13
+ ? 'log'
14
+ : 'info';
15
+ for (const level of DEBUG_LIST) {
16
+ const parts = level.split(':');
17
+ if (parts[0] !== 'agoric') {
18
+ continue;
19
+ }
20
+ if (parts.length > 1) {
21
+ selectedLevel = parts[1];
22
+ } else {
23
+ selectedLevel = 'debug';
24
+ }
12
25
  }
13
- const defaultLevel = anylogger.levels[selectedLevel];
26
+ const selectedCode = anylogger.levels[selectedLevel];
27
+ const globalCode = selectedCode === undefined ? -Infinity : selectedCode;
14
28
 
15
29
  const oldExt = anylogger.ext;
16
30
  anylogger.ext = (l, o) => {
17
31
  l = oldExt(l, o);
18
- l.enabledFor = lvl => defaultLevel >= anylogger.levels[lvl];
32
+ l.enabledFor = lvl => globalCode >= anylogger.levels[lvl];
19
33
 
20
34
  const prefix = l.name.replace(/:/g, ': ');
21
35
  for (const [level, code] of Object.entries(anylogger.levels)) {
22
- if (code > defaultLevel) {
23
- // Disable printing.
24
- l[level] = () => {};
25
- } else {
36
+ if (globalCode >= code) {
26
37
  // Enable the printing with a prefix.
27
38
  const doLog = l[level] || (() => {});
28
39
  l[level] = (...args) => doLog(chalk.bold.blue(`${prefix}:`), ...args);
40
+ } else {
41
+ // Disable printing.
42
+ l[level] = () => {};
29
43
  }
30
44
  }
31
45
  return l;
package/src/bin-agops.js CHANGED
@@ -2,12 +2,14 @@
2
2
  // @ts-check
3
3
  // @jessie-check
4
4
 
5
- /* eslint-disable @jessie.js/no-nested-await */
6
5
  /* global fetch, setTimeout */
7
6
 
7
+ import '@endo/init/pre.js';
8
+
8
9
  import '@agoric/casting/node-fetch-shim.js';
9
10
  import '@endo/init';
10
- import '@endo/init/pre.js';
11
+
12
+ import { E } from '@endo/far';
11
13
 
12
14
  import { execFileSync } from 'child_process';
13
15
  import path from 'path';
@@ -15,7 +17,7 @@ import process from 'process';
15
17
  import anylogger from 'anylogger';
16
18
  import { Command, CommanderError, createCommand } from 'commander';
17
19
  import { makeOracleCommand } from './commands/oracle.js';
18
- import { makeEconomicCommiteeCommand } from './commands/ec.js';
20
+ import { makeGovCommand } from './commands/gov.js';
19
21
  import { makePsmCommand } from './commands/psm.js';
20
22
  import { makeReserveCommand } from './commands/reserve.js';
21
23
  import { makeVaultsCommand } from './commands/vaults.js';
@@ -31,7 +33,7 @@ const program = new Command();
31
33
  program.name(progname).version('unversioned');
32
34
 
33
35
  program.addCommand(makeOracleCommand(logger));
34
- program.addCommand(makeEconomicCommiteeCommand(logger));
36
+ program.addCommand(makeGovCommand(logger));
35
37
  program.addCommand(makePerfCommand(logger));
36
38
  program.addCommand(makePsmCommand(logger));
37
39
  program.addCommand(makeVaultsCommand(logger));
@@ -74,13 +76,11 @@ program.addCommand(makeAuctionCommand(logger, { ...procIO, fetch }));
74
76
  program.addCommand(makeInterCommand(procIO, { fetch }));
75
77
  program.addCommand(makeTestCommand(procIO, { fetch }));
76
78
 
77
- try {
78
- await program.parseAsync(process.argv);
79
- } catch (err) {
79
+ void E.when(program.parseAsync(process.argv), undefined, err => {
80
80
  if (err instanceof CommanderError) {
81
81
  console.error(err.message);
82
82
  } else {
83
83
  console.error(err); // CRASH! show stack trace
84
84
  }
85
85
  process.exit(1);
86
- }
86
+ });
@@ -1,5 +1,6 @@
1
1
  import djson from 'deterministic-json';
2
2
  import TOML from '@iarna/toml';
3
+ import * as Tokens from '@agoric/internal/src/tokens.js';
3
4
 
4
5
  export const STAKING_MAX_VALIDATORS = 150;
5
6
  // Required for IBC connections not to time out.
@@ -13,38 +14,38 @@ export const ICA_HOST_ALLOW_MESSAGES = [
13
14
  ];
14
15
 
15
16
  const Stake = /** @type {const} */ ({
16
- name: 'Agoric Staking Token',
17
+ name: Tokens.Stake.proposedName,
17
18
  description: 'The token used by delegates to stake on the Agoric chain',
18
19
  denom_units: [
19
20
  {
20
- denom: 'ubld',
21
+ denom: Tokens.Stake.denom,
21
22
  exponent: 0,
22
23
  },
23
24
  {
24
25
  denom: 'bld',
25
- exponent: 6,
26
+ exponent: Tokens.Stake.displayInfo.decimalPlaces,
26
27
  },
27
28
  ],
28
- base: 'ubld',
29
+ base: Tokens.Stake.denom,
29
30
  display: 'bld',
30
- symbol: 'BLD',
31
+ symbol: Tokens.Stake.symbol,
31
32
  });
32
33
  const Stable = /** @type {const} */ ({
33
- name: 'Agoric stable token',
34
+ name: Tokens.Stable.proposedName,
34
35
  description: 'The stable token used by the Agoric chain',
35
36
  denom_units: [
36
37
  {
37
- denom: 'uist',
38
+ denom: Tokens.Stable.denom,
38
39
  exponent: 0,
39
40
  },
40
41
  {
41
42
  denom: 'ist',
42
- exponent: 6,
43
+ exponent: Tokens.Stable.displayInfo.decimalPlaces,
43
44
  },
44
45
  ],
45
- base: 'uist',
46
+ base: Tokens.Stable.denom,
46
47
  display: 'ist',
47
- symbol: 'IST',
48
+ symbol: Tokens.Stable.symbol,
48
49
  });
49
50
  export const DENOM_METADATA = /** @type {const} */ ([Stake, Stable]);
50
51
 
@@ -1,14 +1,15 @@
1
- /* eslint-disable @jessie.js/no-nested-await */
2
1
  // @ts-check
3
- /* eslint-disable func-names */
2
+
4
3
  import { InvalidArgumentError } from 'commander';
5
4
  import { makeRpcUtils } from '../lib/rpc.js';
6
5
  import { outputActionAndHint } from '../lib/wallet.js';
7
6
 
8
7
  const { Fail } = assert;
9
8
 
10
- /** @typedef {import('@agoric/governance/src/contractGovernance/typedParamManager.js').ParamTypesMap} ParamTypesMap */
11
- /** @template M @typedef {import('@agoric/governance/src/contractGovernance/typedParamManager.js').ParamTypesMapFromRecord<M>} ParamTypesMapFromRecord */
9
+ /**
10
+ * @import {ParamTypesMap, ParamTypesMapFromRecord} from '@agoric/governance/src/contractGovernance/typedParamManager.js'
11
+ * @import {ParamValueForType} from '@agoric/governance/src/types.js'
12
+ */
12
13
 
13
14
  /**
14
15
  * @template {ParamTypesMap} M
@@ -111,7 +112,7 @@ export const makeAuctionCommand = (
111
112
  * but TimeMath.toRel prodocues a RelativeTime (which may be a bare bigint).
112
113
  *
113
114
  * @param {bigint} relValue
114
- * @returns {import('@agoric/time/src/types').RelativeTimeRecord}
115
+ * @returns {import('@agoric/time').RelativeTimeRecord}
115
116
  */
116
117
  const toRel = relValue => ({ timerBrand, relValue });
117
118
 
@@ -1,4 +1,3 @@
1
- /* eslint-disable @jessie.js/no-nested-await */
2
1
  // @ts-check
3
2
  /* eslint-disable func-names */
4
3
  /* global globalThis, process, setTimeout */
@@ -14,7 +13,17 @@ import {
14
13
  sendAction,
15
14
  } from '../lib/wallet.js';
16
15
 
17
- /** @typedef {import('@agoric/smart-wallet/src/offers.js').OfferSpec} OfferSpec */
16
+ /**
17
+ * @import {OfferSpec} from '@agoric/smart-wallet/src/offers.js'
18
+ * @import {QuestionDetails} from '@agoric/governance/src/types.js'
19
+ */
20
+
21
+ const collectValues = (val, memo) => {
22
+ memo.push(val);
23
+ return memo;
24
+ };
25
+
26
+ const defaultKeyring = process.env.AGORIC_KEYRING_BACKEND || 'test';
18
27
 
19
28
  /**
20
29
  * @param {import('anylogger').Logger} _logger
@@ -27,7 +36,7 @@ import {
27
36
  * delay?: (ms: number) => Promise<void>,
28
37
  * }} [io]
29
38
  */
30
- export const makeEconomicCommiteeCommand = (_logger, io = {}) => {
39
+ export const makeGovCommand = (_logger, io = {}) => {
31
40
  const {
32
41
  // Allow caller to provide access explicitly, but
33
42
  // default to conventional ambient IO facilities.
@@ -39,11 +48,22 @@ export const makeEconomicCommiteeCommand = (_logger, io = {}) => {
39
48
  delay = ms => new Promise(resolve => setTimeout(resolve, ms)),
40
49
  } = io;
41
50
 
42
- const ec = new Command('ec').description('Economic Committee commands');
51
+ const cmd = new Command('gov').description('Electoral governance commands');
52
+ // backwards compatibility with less general "ec" command. To make this work
53
+ // the new CLI options default to the values used for Economic Committee
54
+ cmd.alias('ec');
55
+ cmd.option(
56
+ '--keyring-backend <os|file|test>',
57
+ `keyring's backend (os|file|test) (default "${defaultKeyring}")`,
58
+ defaultKeyring,
59
+ );
43
60
 
44
61
  /** @param {string} literalOrName */
45
62
  const normalizeAddress = literalOrName =>
46
- normalizeAddressWithOptions(literalOrName, { keyringBackend: 'test' });
63
+ normalizeAddressWithOptions(literalOrName, {
64
+ // FIXME does not observe keyring-backend option, which isn't available during arg parsing
65
+ keyringBackend: defaultKeyring,
66
+ });
47
67
 
48
68
  /** @type {(info: unknown, indent?: unknown) => boolean } */
49
69
  const show = (info, indent) =>
@@ -62,17 +82,23 @@ export const makeEconomicCommiteeCommand = (_logger, io = {}) => {
62
82
  * given a sendFrom address; else print it.
63
83
  *
64
84
  * @param {{
65
- * toOffer: (agoricNames: *, current: import('@agoric/smart-wallet/src/smartWallet').CurrentWalletRecord | undefined) => OfferSpec,
85
+ * toOffer: (agoricNames: *, current: import('@agoric/smart-wallet/src/smartWallet.js').CurrentWalletRecord | undefined) => OfferSpec,
66
86
  * sendFrom?: string | undefined,
87
+ * keyringBackend: string,
67
88
  * instanceName?: string,
68
89
  * }} detail
69
90
  * @param {Awaited<ReturnType<makeRpcUtils>>} [optUtils]
70
91
  */
71
- const processOffer = async function ({ toOffer, sendFrom }, optUtils) {
92
+ const processOffer = async function (
93
+ { toOffer, sendFrom, keyringBackend },
94
+ optUtils,
95
+ ) {
72
96
  const networkConfig = await getNetworkConfig(env);
73
97
  const utils = await (optUtils || makeRpcUtils({ fetch }));
74
98
  const { agoricNames, readLatestHead } = utils;
75
99
 
100
+ assert(keyringBackend, 'missing keyring-backend option');
101
+
76
102
  let current;
77
103
  if (sendFrom) {
78
104
  current = await getCurrent(sendFrom, { readLatestHead });
@@ -90,7 +116,7 @@ export const makeEconomicCommiteeCommand = (_logger, io = {}) => {
90
116
  const result = await sendAction(
91
117
  { method: 'executeOffer', offer },
92
118
  {
93
- keyring: { backend: 'test' }, // XXX
119
+ keyring: { backend: keyringBackend },
94
120
  from: sendFrom,
95
121
  verbose: false,
96
122
  ...networkConfig,
@@ -127,29 +153,38 @@ export const makeEconomicCommiteeCommand = (_logger, io = {}) => {
127
153
  show(blockInfo);
128
154
  };
129
155
 
130
- ec.command('committee')
131
- .description('accept invitation to join the economic committee')
156
+ cmd
157
+ .command('committee')
158
+ .description('accept invitation to join a committee')
159
+ .requiredOption(
160
+ '--name <string>',
161
+ 'Committee instance name',
162
+ String,
163
+ 'economicCommittee',
164
+ )
132
165
  .option('--voter <number>', 'Voter number', Number, 0)
133
166
  .option(
134
167
  '--offerId <string>',
135
168
  'Offer id',
136
169
  String,
137
- `ecCommittee-${Date.now()}`,
170
+ `gov-committee-${Date.now()}`,
138
171
  )
139
172
  .option(
140
173
  '--send-from <name-or-address>',
141
174
  'Send from address',
142
175
  normalizeAddress,
143
176
  )
144
- .action(async function (opts) {
177
+ .action(async function (opts, options) {
178
+ const { name: instanceName } = opts;
179
+
145
180
  /** @type {Parameters<typeof processOffer>[0]['toOffer']} */
146
181
  const toOffer = (agoricNames, current) => {
147
- const instance = agoricNames.instance.economicCommittee;
148
- assert(instance, `missing economicCommittee`);
182
+ const instance = agoricNames.instance[instanceName];
183
+ assert(instance, `missing ${instanceName}`);
149
184
 
150
185
  if (current) {
151
186
  const found = findContinuingIds(current, agoricNames);
152
- abortIfSeen('economicCommittee', found);
187
+ abortIfSeen(instanceName, found);
153
188
  }
154
189
 
155
190
  return {
@@ -165,28 +200,37 @@ export const makeEconomicCommiteeCommand = (_logger, io = {}) => {
165
200
 
166
201
  await processOffer({
167
202
  toOffer,
168
- instanceName: 'economicCommittee',
169
- ...opts,
203
+ instanceName,
204
+ sendFrom: opts.sendFrom,
205
+ keyringBackend: options.optsWithGlobals().keyringBackend,
170
206
  });
171
207
  });
172
208
 
173
- ec.command('charter')
209
+ cmd
210
+ .command('charter')
174
211
  .description('accept the charter invitation')
175
- .option('--offerId <string>', 'Offer id', String, `ecCharter-${Date.now()}`)
212
+ .requiredOption(
213
+ '--name <string>',
214
+ 'Charter instance name',
215
+ 'economicCommitteeCharter',
216
+ )
217
+ .option('--offerId <string>', 'Offer id', String, `charter-${Date.now()}`)
176
218
  .option(
177
219
  '--send-from <name-or-address>',
178
220
  'Send from address',
179
221
  normalizeAddress,
180
222
  )
181
- .action(async function (opts) {
223
+ .action(async function (opts, options) {
224
+ const { name: instanceName } = opts;
225
+
182
226
  /** @type {Parameters<typeof processOffer>[0]['toOffer']} */
183
227
  const toOffer = (agoricNames, current) => {
184
- const instance = agoricNames.instance.econCommitteeCharter;
185
- assert(instance, `missing econCommitteeCharter`);
228
+ const instance = agoricNames.instance[instanceName];
229
+ assert(instance, `missing ${instanceName}`);
186
230
 
187
231
  if (current) {
188
232
  const found = findContinuingIds(current, agoricNames);
189
- abortIfSeen('econCommitteeCharter', found);
233
+ abortIfSeen(instanceName, found);
190
234
  }
191
235
 
192
236
  return {
@@ -202,12 +246,14 @@ export const makeEconomicCommiteeCommand = (_logger, io = {}) => {
202
246
 
203
247
  await processOffer({
204
248
  toOffer,
205
- instanceName: 'econCommitteeCharter',
206
- ...opts,
249
+ instanceName,
250
+ sendFrom: opts.sendFrom,
251
+ keyringBackend: options.optsWithGlobals().keyringBackend,
207
252
  });
208
253
  });
209
254
 
210
- ec.command('find-continuing-id')
255
+ cmd
256
+ .command('find-continuing-id')
211
257
  .description('print id of specified voting continuing invitation')
212
258
  .requiredOption(
213
259
  '--from <name-or-address>',
@@ -233,7 +279,8 @@ export const makeEconomicCommiteeCommand = (_logger, io = {}) => {
233
279
  console.log(match.offerId);
234
280
  });
235
281
 
236
- ec.command('find-continuing-ids')
282
+ cmd
283
+ .command('find-continuing-ids')
237
284
  .description('print records of voting continuing invitations')
238
285
  .requiredOption(
239
286
  '--from <name-or-address>',
@@ -245,12 +292,27 @@ export const makeEconomicCommiteeCommand = (_logger, io = {}) => {
245
292
  const current = await getCurrent(opts.from, { readLatestHead });
246
293
 
247
294
  const found = findContinuingIds(current, agoricNames);
248
- found.forEach(it => show({ ...it, address: opts.from }));
295
+ for (const it of found) {
296
+ show({ ...it, address: opts.from });
297
+ }
249
298
  });
250
299
 
251
- ec.command('vote')
252
- .description('vote on a question (hard-coded for now))')
253
- .option('--offerId <number>', 'Offer id', String, `ecVote-${Date.now()}`)
300
+ cmd
301
+ .command('vote')
302
+ .description('vote on latest question')
303
+ .requiredOption(
304
+ '--instance <string>',
305
+ 'Committee name under agoricNames.instances',
306
+ String,
307
+ 'economicCommittee',
308
+ )
309
+ .requiredOption(
310
+ '--pathname <string>',
311
+ 'Committee name under published.committees',
312
+ String,
313
+ 'Economic_Committee',
314
+ )
315
+ .option('--offerId <number>', 'Offer id', String, `gov-vote-${Date.now()}`)
254
316
  .requiredOption(
255
317
  '--forPosition <number>',
256
318
  'index of one position to vote for (within the question description.positions); ',
@@ -261,17 +323,18 @@ export const makeEconomicCommiteeCommand = (_logger, io = {}) => {
261
323
  'Send from address',
262
324
  normalizeAddress,
263
325
  )
264
- .action(async function (opts) {
326
+ .action(async function (opts, options) {
265
327
  const utils = await makeRpcUtils({ fetch });
266
328
  const { readLatestHead } = utils;
267
329
 
268
330
  const info = await readLatestHead(
269
- 'published.committees.Economic_Committee.latestQuestion',
331
+ `published.committees.${opts.pathname}.latestQuestion`,
270
332
  ).catch(err => {
271
333
  throw new CommanderError(1, 'VSTORAGE_FAILURE', err.message);
272
334
  });
335
+
273
336
  // XXX runtime shape-check
274
- const questionDesc = /** @type {any} */ (info);
337
+ const questionDesc = /** @type {QuestionDetails} */ (info);
275
338
 
276
339
  // TODO support multiple position arguments
277
340
  const chosenPositions = [questionDesc.positions[opts.forPosition]];
@@ -280,9 +343,7 @@ export const makeEconomicCommiteeCommand = (_logger, io = {}) => {
280
343
  /** @type {Parameters<typeof processOffer>[0]['toOffer']} */
281
344
  const toOffer = (agoricNames, current) => {
282
345
  const cont = current ? findContinuingIds(current, agoricNames) : [];
283
- const votingRight = cont.find(
284
- it => it.instance === agoricNames.instance.economicCommittee,
285
- );
346
+ const votingRight = cont.find(it => it.instanceName === opts.instance);
286
347
  if (!votingRight) {
287
348
  console.debug('continuing ids', cont, 'for', current);
288
349
  throw new CommanderError(
@@ -307,8 +368,89 @@ export const makeEconomicCommiteeCommand = (_logger, io = {}) => {
307
368
  };
308
369
  };
309
370
 
310
- await processOffer({ toOffer, sendFrom: opts.sendFrom }, utils);
371
+ await processOffer(
372
+ {
373
+ toOffer,
374
+ sendFrom: opts.sendFrom,
375
+ keyringBackend: options.optsWithGlobals().keyringBackend,
376
+ },
377
+ utils,
378
+ );
379
+ });
380
+
381
+ cmd
382
+ .command('proposePauseOffers')
383
+ .description('propose a vote to pause offers')
384
+ .option(
385
+ '--send-from <name-or-address>',
386
+ 'Send from address',
387
+ normalizeAddress,
388
+ )
389
+ .option(
390
+ '--offerId <string>',
391
+ 'Offer id',
392
+ String,
393
+ `proposePauseOffers-${Date.now()}`,
394
+ )
395
+ .requiredOption(
396
+ '--instance <string>',
397
+ 'name of governed instance in agoricNames',
398
+ )
399
+ .requiredOption(
400
+ '--substring <string>',
401
+ 'an offer string to pause (can be repeated)',
402
+ collectValues,
403
+ [],
404
+ )
405
+ .option(
406
+ '--deadline <minutes>',
407
+ 'minutes from now to close the vote',
408
+ Number,
409
+ 1,
410
+ )
411
+ .action(async function (opts, options) {
412
+ const { instance: instanceName } = opts;
413
+
414
+ /** @type {Parameters<typeof processOffer>[0]['toOffer']} */
415
+ const toOffer = (agoricNames, current) => {
416
+ const instance = agoricNames.instance[instanceName];
417
+ assert(instance, `missing ${instanceName}`);
418
+ assert(current, 'missing current wallet');
419
+
420
+ const known = findContinuingIds(current, agoricNames);
421
+
422
+ assert(known, 'could not find committee acceptance offer id');
423
+
424
+ // TODO magic string
425
+ const match = known.find(
426
+ r => r.description === 'charter member invitation',
427
+ );
428
+ assert(match, 'no offer found for charter member invitation');
429
+
430
+ return {
431
+ id: opts.offerId,
432
+ invitationSpec: {
433
+ source: 'continuing',
434
+ previousOffer: match.offerId,
435
+ invitationMakerName: 'VoteOnPauseOffers',
436
+ // ( instance, strings list, timer deadline seconds )
437
+ invitationArgs: harden([
438
+ instance,
439
+ opts.substring,
440
+ BigInt(opts.deadline * 60 + Math.round(Date.now() / 1000)),
441
+ ]),
442
+ },
443
+ proposal: {},
444
+ };
445
+ };
446
+
447
+ await processOffer({
448
+ toOffer,
449
+ instanceName,
450
+ sendFrom: opts.sendFrom,
451
+ keyringBackend: options.optsWithGlobals().keyringBackend,
452
+ });
311
453
  });
312
454
 
313
- return ec;
455
+ return cmd;
314
456
  };