agoric 0.21.2-dev-cbcea8c.0.cbcea8c → 0.21.2-dev-5ff5e7a.0.5ff5e7a

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.21.2-dev-cbcea8c.0.cbcea8c",
3
+ "version": "0.21.2-dev-5ff5e7a.0.5ff5e7a",
4
4
  "description": "Manage the Agoric Javascript smart contract platform",
5
5
  "type": "module",
6
6
  "main": "src/main.js",
@@ -30,28 +30,27 @@
30
30
  "lint:eslint": "node ../../scripts/eslint-repo.mjs ."
31
31
  },
32
32
  "devDependencies": {
33
- "@agoric/cosmic-swingset": "0.41.4-dev-cbcea8c.0.cbcea8c",
34
- "@agoric/deploy-script-support": "0.10.4-dev-cbcea8c.0.cbcea8c",
33
+ "@agoric/cosmic-swingset": "0.41.4-dev-5ff5e7a.0.5ff5e7a",
34
+ "@agoric/deploy-script-support": "0.10.4-dev-5ff5e7a.0.5ff5e7a",
35
35
  "ava": "^7.0.0",
36
36
  "c8": "^10.1.2"
37
37
  },
38
38
  "dependencies": {
39
- "@agoric/access-token": "0.4.22-dev-cbcea8c.0.cbcea8c",
40
- "@agoric/cache": "0.3.3-dev-cbcea8c.0.cbcea8c",
41
- "@agoric/casting": "0.4.3-dev-cbcea8c.0.cbcea8c",
42
- "@agoric/client-utils": "0.1.1-dev-cbcea8c.0.cbcea8c",
43
- "@agoric/cosmic-proto": "0.4.1-dev-cbcea8c.0.cbcea8c",
44
- "@agoric/ertp": "0.16.3-dev-cbcea8c.0.cbcea8c",
45
- "@agoric/governance": "0.10.4-dev-cbcea8c.0.cbcea8c",
46
- "@agoric/inter-protocol": "0.16.2-dev-cbcea8c.0.cbcea8c",
47
- "@agoric/internal": "0.3.3-dev-cbcea8c.0.cbcea8c",
48
- "@agoric/network": "0.1.1-dev-cbcea8c.0.cbcea8c",
49
- "@agoric/smart-wallet": "0.5.4-dev-cbcea8c.0.cbcea8c",
50
- "@agoric/store": "0.9.3-dev-cbcea8c.0.cbcea8c",
51
- "@agoric/swingset-vat": "0.32.3-dev-cbcea8c.0.cbcea8c",
52
- "@agoric/vats": "0.15.2-dev-cbcea8c.0.cbcea8c",
53
- "@agoric/zoe": "0.26.3-dev-cbcea8c.0.cbcea8c",
54
- "@agoric/zone": "0.2.3-dev-cbcea8c.0.cbcea8c",
39
+ "@agoric/access-token": "0.4.22-dev-5ff5e7a.0.5ff5e7a",
40
+ "@agoric/cache": "0.3.3-dev-5ff5e7a.0.5ff5e7a",
41
+ "@agoric/casting": "0.4.3-dev-5ff5e7a.0.5ff5e7a",
42
+ "@agoric/client-utils": "0.1.1-dev-5ff5e7a.0.5ff5e7a",
43
+ "@agoric/cosmic-proto": "0.4.1-dev-5ff5e7a.0.5ff5e7a",
44
+ "@agoric/ertp": "0.16.3-dev-5ff5e7a.0.5ff5e7a",
45
+ "@agoric/governance": "0.10.4-dev-5ff5e7a.0.5ff5e7a",
46
+ "@agoric/internal": "0.3.3-dev-5ff5e7a.0.5ff5e7a",
47
+ "@agoric/network": "0.1.1-dev-5ff5e7a.0.5ff5e7a",
48
+ "@agoric/smart-wallet": "0.5.4-dev-5ff5e7a.0.5ff5e7a",
49
+ "@agoric/store": "0.9.3-dev-5ff5e7a.0.5ff5e7a",
50
+ "@agoric/swingset-vat": "0.32.3-dev-5ff5e7a.0.5ff5e7a",
51
+ "@agoric/vats": "0.15.2-dev-5ff5e7a.0.5ff5e7a",
52
+ "@agoric/zoe": "0.26.3-dev-5ff5e7a.0.5ff5e7a",
53
+ "@agoric/zone": "0.2.3-dev-5ff5e7a.0.5ff5e7a",
55
54
  "@cosmjs/crypto": "^0.36.0",
56
55
  "@cosmjs/encoding": "^0.36.0",
57
56
  "@cosmjs/math": "^0.36.0",
@@ -102,5 +101,5 @@
102
101
  "engines": {
103
102
  "node": "^22.11"
104
103
  },
105
- "gitHead": "cbcea8c2415f2c9c4bc1ea9ff90730f2773bafaa"
104
+ "gitHead": "5ff5e7aa9e8c42795c47aabc7222eb56a2915011"
106
105
  }
package/src/bin-agops.js CHANGED
@@ -11,11 +11,7 @@ import path from 'node:path';
11
11
  import process from 'node:process';
12
12
  import anylogger from '@agoric/internal/vendor/anylogger.js';
13
13
  import { Command, CommanderError, createCommand } from 'commander';
14
- import { makeOracleCommand } from './commands/oracle.js';
15
14
  import { makeGovCommand } from './commands/gov.js';
16
- import { makePsmCommand } from './commands/psm.js';
17
- import { makeReserveCommand } from './commands/reserve.js';
18
- import { makeVaultsCommand } from './commands/vaults.js';
19
15
  import { makePerfCommand } from './commands/perf.js';
20
16
  import { makeTestCommand } from './commands/test-upgrade.js';
21
17
 
@@ -27,8 +23,6 @@ program.name(progname).version('unversioned');
27
23
 
28
24
  program.addCommand(makeGovCommand(logger));
29
25
  program.addCommand(makePerfCommand(logger));
30
- program.addCommand(makePsmCommand(logger));
31
- program.addCommand(makeVaultsCommand(logger));
32
26
 
33
27
  /**
34
28
  * XXX Threading I/O powers has gotten a bit jumbled.
@@ -63,8 +57,6 @@ const procIO = {
63
57
  setTimeout,
64
58
  };
65
59
 
66
- program.addCommand(makeOracleCommand(procIO, logger));
67
- program.addCommand(makeReserveCommand(logger, procIO));
68
60
  program.addCommand(makeTestCommand(procIO, { fetch }));
69
61
 
70
62
  void E.when(program.parseAsync(process.argv), undefined, err => {
@@ -1,7 +1,6 @@
1
1
  // DO NOT EDIT - automatically generated by get-sdk-package-names.js
2
2
  // prettier-ignore
3
3
  export default [
4
- "@aglocal/benchmark",
5
4
  "@aglocal/boot",
6
5
  "@aglocal/deployment",
7
6
  "@aglocal/fast-usdc-contract",
@@ -28,7 +27,6 @@ export default [
28
27
  "@agoric/fast-usdc",
29
28
  "@agoric/governance",
30
29
  "@agoric/import-manager",
31
- "@agoric/inter-protocol",
32
30
  "@agoric/internal",
33
31
  "@agoric/kmarshal",
34
32
  "@agoric/network",
@@ -1,414 +0,0 @@
1
- // @ts-check
2
- /* eslint-disable func-names */
3
- /* eslint-env node */
4
- import {
5
- fetchEnvNetworkConfig,
6
- makeAgoricNames,
7
- makeVstorageKit,
8
- makeWalletUtils,
9
- storageHelper,
10
- } from '@agoric/client-utils';
11
- import { Offers } from '@agoric/inter-protocol/src/clientSupport.js';
12
- import { oracleBrandFeedName } from '@agoric/inter-protocol/src/proposals/utils.js';
13
- import { Fail } from '@endo/errors';
14
- import { Nat } from '@endo/nat';
15
- import { Command } from 'commander';
16
- import { inspect } from 'node:util';
17
- import { normalizeAddressWithOptions } from '../lib/chain.js';
18
- import { bigintReplacer } from '../lib/format.js';
19
- import {
20
- getCurrent,
21
- outputAction,
22
- sendAction,
23
- sendHint,
24
- } from '../lib/wallet.js';
25
-
26
- /**
27
- * @import {PriceAuthority, PriceDescription, PriceQuote, PriceQuoteValue, PriceQuery,} from '@agoric/zoe/tools/types.js';
28
- * @import {Writable} from 'stream';
29
- * @import {Logger} from '@agoric/internal/vendor/anylogger.js';
30
- * @import {OfferSpec} from '@agoric/smart-wallet/src/offers.js';
31
- * @import {TimestampRecord} from '@agoric/time';
32
- */
33
-
34
- // XXX support other decimal places
35
- const COSMOS_UNIT = 1_000_000n;
36
- /** @param {number} num */
37
- const scaleDecimals = num => BigInt(Math.round(num * Number(COSMOS_UNIT)));
38
-
39
- /**
40
- * Prints JSON output to stdout and diagnostic info (like logs) to stderr
41
- *
42
- * @param {{
43
- * createCommand: typeof import('commander').createCommand,
44
- * env: Partial<Record<string, string>>,
45
- * execFileSync: typeof import('child_process').execFileSync,
46
- * now: () => number,
47
- * setTimeout: typeof globalThis.setTimeout,
48
- * stderr: Pick<Writable,'write'>,
49
- * stdout: Pick<Writable,'write'>,
50
- * }} process
51
- * @param {Logger} [logger]
52
- */
53
- export const makeOracleCommand = (
54
- { env, execFileSync, setTimeout, stderr, stdout },
55
- logger,
56
- ) => {
57
- /**
58
- * @param {number} ms
59
- * @returns {Promise<void>}
60
- */
61
- const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
62
-
63
- const oracle = new Command('oracle')
64
- .description('Oracle commands')
65
- .usage(
66
- `
67
- WALLET=my-wallet
68
- export AGORIC_NET=ollinet
69
-
70
- # provision wallet if necessary
71
- agd keys add $WALLET
72
- # provision with faucet, e.g.
73
- open https://ollinet.faucet.agoric.net/ # and paste the key and choose client: smart-wallet
74
-
75
- # confirm funds
76
- agoric wallet list
77
- agoric wallet show —from $WALLET
78
-
79
- # prepare an offer to send
80
- # (offerId is optional but best to specify as each must be higher than the last and the default value is a huge number)
81
- agops oracle accept --offerId 12 > offer-12.json
82
-
83
- # sign and send
84
- agoric wallet send --from $WALLET --offer offer-12.json
85
- `,
86
- )
87
- .option(
88
- '--keyring-backend <os|file|test>',
89
- `keyring's backend (os|file|test) (default "${
90
- env.AGORIC_KEYRING_BACKEND || 'os'
91
- }")`,
92
- env.AGORIC_KEYRING_BACKEND,
93
- );
94
-
95
- const normalizeAddress = literalOrName =>
96
- normalizeAddressWithOptions(literalOrName, oracle.opts(), {
97
- execFileSync,
98
- });
99
-
100
- const rpcTools = async () => {
101
- // XXX pass fetch to getNetworkConfig() explicitly
102
- const networkConfig = await fetchEnvNetworkConfig({
103
- env: process.env,
104
- fetch,
105
- });
106
- const vsk = makeVstorageKit({ fetch }, networkConfig);
107
- const agoricNames = await makeAgoricNames(vsk.fromBoard, vsk.vstorage);
108
-
109
- const lookupPriceAggregatorInstance = ([brandIn, brandOut]) => {
110
- const name = oracleBrandFeedName(brandIn, brandOut);
111
- const instance = agoricNames.instance[name];
112
- if (!instance) {
113
- logger && logger.debug('known instances:', agoricNames.instance);
114
- throw Error(`Unknown instance ${name}`);
115
- }
116
- return instance;
117
- };
118
-
119
- return { ...vsk, networkConfig, lookupPriceAggregatorInstance };
120
- };
121
-
122
- oracle
123
- .command('accept')
124
- .description('accept invitation to operate an oracle')
125
- .requiredOption(
126
- '--pair [brandIn.brandOut]',
127
- 'token pair (brandIn.brandOut)',
128
- s => s.split('.'),
129
- ['ATOM', 'USD'],
130
- )
131
- .option(
132
- '--offerId <string>',
133
- 'Offer id',
134
- String,
135
- `oracleAccept-${Date.now()}`,
136
- )
137
- .action(async function (opts) {
138
- const { lookupPriceAggregatorInstance } = await rpcTools();
139
- const instance = lookupPriceAggregatorInstance(opts.pair);
140
-
141
- /** @type {OfferSpec} */
142
- const offer = {
143
- id: opts.offerId,
144
- invitationSpec: {
145
- source: 'purse',
146
- instance,
147
- description: 'oracle invitation',
148
- },
149
- proposal: {},
150
- };
151
-
152
- outputAction(
153
- {
154
- method: 'executeOffer',
155
- offer,
156
- },
157
- stdout,
158
- );
159
-
160
- stderr.write(sendHint);
161
- });
162
-
163
- oracle
164
- .command('pushPriceRound')
165
- .description('add a price for a round to a fluxAggregator')
166
- .option(
167
- '--offerId <string>',
168
- 'Offer id',
169
- String,
170
- `pushPriceRound-${Date.now()}`,
171
- )
172
- .requiredOption(
173
- '--oracleAdminAcceptOfferId <string>',
174
- 'offer that had continuing invitation result',
175
- String,
176
- )
177
- .requiredOption('--price <number>', 'price', Number)
178
- .option('--roundId <number>', 'round', Number)
179
- .action(async function (opts) {
180
- const { offerId } = opts;
181
- const unitPrice = scaleDecimals(opts.price);
182
- const roundId = 'roundId' in opts ? Nat(opts.roundId) : undefined;
183
-
184
- const offer = Offers.fluxAggregator.PushPrice(
185
- {},
186
- { offerId, unitPrice, roundId },
187
- opts.oracleAdminAcceptOfferId,
188
- );
189
-
190
- outputAction(
191
- {
192
- method: 'executeOffer',
193
- offer,
194
- },
195
- stdout,
196
- );
197
-
198
- stderr.write(sendHint);
199
- });
200
-
201
- const findOracleCap = async (instance, from, readPublished) => {
202
- const current = await getCurrent(from, { readPublished });
203
-
204
- const { offerToUsedInvitation: entries } = /** @type {any} */ (current);
205
- Array.isArray(entries) || Fail`entries must be an array: ${entries}`;
206
-
207
- for (const [offerId, { value }] of entries) {
208
- /** @type {{ description: string, instance: unknown }[]} */
209
- const [{ description, instance: candidate }] = value;
210
- if (description === 'oracle invitation' && candidate === instance) {
211
- return offerId;
212
- }
213
- }
214
- };
215
-
216
- oracle
217
- .command('find-continuing-id')
218
- .description('print id of specified oracle continuing invitation')
219
- .requiredOption(
220
- '--from <address>',
221
- 'wallet address literal or name',
222
- normalizeAddress,
223
- )
224
- .requiredOption(
225
- '--pair [brandIn.brandOut]',
226
- 'token pair (brandIn.brandOut)',
227
- s => s.split('.'),
228
- )
229
- .action(async opts => {
230
- const { readPublished, lookupPriceAggregatorInstance } = await rpcTools();
231
- const instance = lookupPriceAggregatorInstance(opts.pair);
232
-
233
- const offerId = await findOracleCap(instance, opts.from, readPublished);
234
- if (!offerId) {
235
- console.error('No continuing ids found');
236
- }
237
- console.log(offerId);
238
- });
239
-
240
- oracle
241
- .command('query')
242
- .description('return current aggregated (median) price')
243
- .requiredOption(
244
- '--pair [brandIn.brandOut]',
245
- 'token pair (brandIn.brandOut)',
246
- s => s.split('.'),
247
- ['ATOM', 'USD'],
248
- )
249
- .action(async function (opts) {
250
- const { pair } = opts;
251
- const { vstorage, fromBoard } = await rpcTools();
252
-
253
- const capDataStr = await vstorage.readLatest(
254
- `published.priceFeed.${pair[0]}-${pair[1]}_price_feed`,
255
- );
256
- const capDatas = storageHelper.unserializeTxt(capDataStr, fromBoard);
257
-
258
- console.log(inspect(capDatas[0], { depth: 10, colors: true }));
259
- });
260
-
261
- const show = (info, indent = false) =>
262
- stdout.write(
263
- `${JSON.stringify(info, bigintReplacer, indent ? 2 : undefined)}\n`,
264
- );
265
- /** @param {bigint} secs */
266
- const fmtSecs = secs => new Date(Number(secs) * 1000).toISOString();
267
-
268
- oracle
269
- .command('setPrice')
270
- .description('set price by pushing from multiple operators')
271
- .requiredOption(
272
- '--pair [brandIn.brandOut]',
273
- 'token pair (brandIn.brandOut)',
274
- s => s.split('.'),
275
- ['ATOM', 'USD'],
276
- )
277
- .requiredOption(
278
- '--keys [key1,key2,...]',
279
- 'key names of operators (comma separated)',
280
- s => s.split(','),
281
- ['gov1', 'gov2'],
282
- )
283
- .requiredOption('--price <number>', 'price', Number)
284
- .action(
285
- async (
286
- /**
287
- * @type {{
288
- * pair: [brandIn: string, brandOut: string],
289
- * keys: string[],
290
- * price: number,
291
- * }}
292
- */ { pair, keys, price },
293
- ) => {
294
- const {
295
- readLatestHead,
296
- readPublished,
297
- networkConfig,
298
- lookupPriceAggregatorInstance,
299
- } = await rpcTools();
300
- const wutil = await makeWalletUtils({ fetch, delay }, networkConfig);
301
- const unitPrice = scaleDecimals(price);
302
-
303
- const feedPath = `published.priceFeed.${pair[0]}-${pair[1]}_price_feed`;
304
-
305
- const readPrice = () =>
306
- /** @type {Promise<PriceDescription>} */ (
307
- readLatestHead(feedPath).catch(() => {
308
- const viewer = `https://vstorage.agoric.net/#${networkConfig.rpcAddrs[0]}|published,published.priceFeed|${feedPath}`;
309
- stderr.write(`no existing price data; see ${viewer}`);
310
- return undefined;
311
- })
312
- );
313
-
314
- const r4 = x => Math.round(x * 10000) / 10000; // XXX 4 decimals arbitrary
315
- const fmtFeed = ({
316
- amountIn: { value: valueIn },
317
- amountOut: { value: valueOut },
318
- timestamp: { absValue: ts },
319
- }) => ({
320
- timestamp: fmtSecs(ts),
321
- price: r4(Number(valueOut) / Number(valueIn)),
322
- });
323
- const before = await readPrice();
324
- if (before) {
325
- show(fmtFeed(before));
326
- }
327
-
328
- const keyOrder = keys.map(normalizeAddress);
329
- if (before) {
330
- console.error(
331
- 'Choose lead oracle operator order based on latestRound...',
332
- );
333
-
334
- const latestRoundP =
335
- /** @type {Promise<{roundId: number, startedAt: TimestampRecord, startedBy: string}>} */ (
336
- readLatestHead(
337
- `published.priceFeed.${pair[0]}-${pair[1]}_price_feed.latestRound`,
338
- )
339
- );
340
- await Promise.race([
341
- delay(5000),
342
- latestRoundP.then(round => {
343
- const { roundId, startedAt, startedBy } = round;
344
- show({
345
- startedAt: fmtSecs(startedAt.absValue),
346
- roundId,
347
- startedBy,
348
- });
349
- if (startedBy === keyOrder[0]) {
350
- keyOrder.reverse();
351
- }
352
- }),
353
- ]).catch(err => {
354
- stderr.write(err);
355
- });
356
- }
357
-
358
- const instance = lookupPriceAggregatorInstance(pair);
359
- const adminOfferIds = {};
360
- for await (const from of keyOrder) {
361
- adminOfferIds[from] = await findOracleCap(
362
- instance,
363
- from,
364
- readPublished,
365
- );
366
- if (!adminOfferIds[from]) {
367
- console.error(
368
- `Failed to find an offer accepting oracle invitation for ${from}. Accept and try again:`,
369
- );
370
- console.error(
371
- ` agops oracle accept > accept.json; agoric wallet send --from ${from} --offer accept.json`,
372
- );
373
- }
374
- }
375
- assert(
376
- Object.values(adminOfferIds).every(x => x),
377
- 'Missing oracle admin offer ids',
378
- );
379
-
380
- console.error('pushPrice from each:', keyOrder);
381
- for await (const from of keyOrder) {
382
- const oracleAdminAcceptOfferId = adminOfferIds[from];
383
- show({ from, oracleAdminAcceptOfferId });
384
- const offerId = `pushPrice-${Date.now()}`;
385
- const offer = Offers.fluxAggregator.PushPrice(
386
- {},
387
- { offerId, unitPrice },
388
- oracleAdminAcceptOfferId,
389
- );
390
-
391
- const { home, keyringBackend: backend } = oracle.opts();
392
- const tools = { ...networkConfig, execFileSync, delay, stdout };
393
- const result = await sendAction(
394
- { method: 'executeOffer', offer },
395
- { keyring: { home, backend }, from, verbose: false, ...tools },
396
- );
397
- assert(result); // Not dry-run
398
- const { timestamp, txhash, height } = result;
399
- console.error('pushPrice', price, 'offer broadcast');
400
- show({ timestamp, height, offerId: offer.id, txhash });
401
- const found = await wutil.pollOffer(from, offer.id, result.height);
402
- console.error('pushPrice', price, 'offer satisfied');
403
- show(found);
404
- }
405
-
406
- const after = await readPrice();
407
- if (after) {
408
- console.error('price set:');
409
- show(fmtFeed(after));
410
- }
411
- },
412
- );
413
- return oracle;
414
- };
@@ -1,288 +0,0 @@
1
- // @ts-check
2
- /* eslint-disable func-names */
3
- /* eslint-env node */
4
- import {
5
- fetchEnvNetworkConfig,
6
- makeAgoricNames,
7
- makeVstorageKit,
8
- storageHelper,
9
- } from '@agoric/client-utils';
10
- import { Offers } from '@agoric/inter-protocol/src/clientSupport.js';
11
- import { Command } from 'commander';
12
- import { asPercent } from '../lib/format.js';
13
- import { outputExecuteOfferAction } from '../lib/wallet.js';
14
-
15
- /**
16
- * @import {Logger} from '@agoric/internal/vendor/anylogger.js';
17
- * @import {OfferSpec} from '@agoric/smart-wallet/src/offers.js';
18
- */
19
-
20
- const networkConfig = await fetchEnvNetworkConfig({ env: process.env, fetch });
21
-
22
- // Adapted from https://gist.github.com/dckc/8b5b2f16395cb4d7f2ff340e0bc6b610#file-psm-tool
23
-
24
- /**
25
- * Integration testing.
26
- * These are against a live network so don't run in CI.
27
- *
28
- * AGORIC_NET=ollinet bin/agops psm swap --wantMinted 6 --feePct 0.01 --offerId 123 | jq '.body |fromjson | .offer.id' # should be 123
29
- */
30
-
31
- /**
32
- * @template K, V
33
- * @typedef {[key: K, val: V]} Entry<K,V>
34
- */
35
-
36
- const last = xs => xs[xs.length - 1];
37
-
38
- function collectValues(val, memo) {
39
- memo.push(val);
40
- return memo;
41
- }
42
-
43
- /**
44
- * @param {Logger} logger
45
- */
46
- export const makePsmCommand = logger => {
47
- const psm = new Command('psm').description('PSM commands').usage(
48
- `
49
- WALLET=my-wallet
50
- export AGORIC_NET=ollinet
51
-
52
- # provision wallet if necessary
53
- agd keys add $WALLET
54
- # provision with faucet, e.g.
55
- open https://ollinet.faucet.agoric.net/ # and paste the key and choose client: smart-wallet
56
-
57
- # confirm funds
58
- agoric wallet list
59
- agoric wallet show —from $WALLET
60
-
61
- # prepare an offer to send
62
- # (offerId is optional but best to specify as each must be higher than the last and the default value is a huge number)
63
- agops psm swap --wantMinted 6 --feePct 0.01 --offerId 12 > offer-12.json
64
-
65
- # watch for results in one terminal
66
- agoric wallet watch --from $WALLET
67
-
68
- # sign and send in another
69
- agoric wallet send --from $WALLET --offer offer-12.json
70
- # that spits out a CLI command to run
71
- `,
72
- );
73
-
74
- const rpcTools = async () => {
75
- const vsk = await makeVstorageKit({ fetch }, networkConfig);
76
- const agoricNames = await makeAgoricNames(vsk.fromBoard, vsk.vstorage);
77
-
78
- const lookupPsmInstance = ([minted, anchor]) => {
79
- const name = `psm-${minted}-${anchor}`;
80
- const instance = agoricNames.instance[name];
81
- if (!instance) {
82
- logger.debug('known instances:', agoricNames.instance);
83
- throw Error(`Unknown instance ${name}`);
84
- }
85
- return instance;
86
- };
87
-
88
- /**
89
- *
90
- * @param {[Minted: string, Anchor: string]} pair
91
- */
92
- const getGovernanceState = async ([Minted, Anchor]) => {
93
- const govContent = await vsk.vstorage.readLatest(
94
- `published.psm.${Minted}.${Anchor}.governance`,
95
- );
96
- assert(govContent, 'no gov content');
97
- const { current: governance } = last(
98
- storageHelper.unserializeTxt(govContent, vsk.fromBoard),
99
- );
100
- const { [`psm.${Minted}.${Anchor}`]: instance } = agoricNames.instance;
101
-
102
- return { instance, governance };
103
- };
104
-
105
- return { ...vsk, agoricNames, lookupPsmInstance, getGovernanceState };
106
- };
107
-
108
- psm
109
- .command('list')
110
- .description('list all PSMs in network')
111
- .action(async function () {
112
- const { vstorage } = await rpcTools();
113
- const mints = await vstorage.keys('published.psm');
114
- for (const minted of mints) {
115
- const anchors = await vstorage.keys(`published.psm.${minted}`);
116
- for (const anchor of anchors) {
117
- process.stdout.write(`${minted}.${anchor}\n`);
118
- }
119
- }
120
- });
121
-
122
- psm
123
- .command('info')
124
- .description('show governance parameters of the PSM')
125
- // TODO DRY with https://github.com/Agoric/agoric-sdk/issues/6181
126
- .requiredOption(
127
- '--pair [Minted.Anchor]',
128
- 'token pair (Minted.Anchor)',
129
- s => s.split('.'),
130
- ['IST', 'AUSD'],
131
- )
132
- .action(async function (opts) {
133
- const { pair } = opts;
134
- const { getGovernanceState } = await rpcTools();
135
- const { governance } = await getGovernanceState(pair);
136
- console.log('psm governance params', Object.keys(governance));
137
- console.log('MintLimit', governance.MintLimit.value);
138
- console.log(
139
- 'WantMintedFee',
140
- asPercent(governance.WantMintedFee.value),
141
- '%',
142
- );
143
- console.log(
144
- 'GiveMintedFee',
145
- asPercent(governance.GiveMintedFee.value),
146
- '%',
147
- );
148
- });
149
-
150
- psm
151
- .command('swap')
152
- .description('prepare an offer to swap')
153
- // TODO DRY
154
- .option(
155
- '--pair [Minted.Anchor]',
156
- 'token pair (Minted.Anchor)',
157
- s => s.split('.'),
158
- ['IST', 'AUSD'],
159
- )
160
- // wantMinted and giveMinted options conflict.
161
- // TODO use .conflicts() after https://github.com/Agoric/agoric-sdk/issues/6181
162
- .option('--wantMinted <DOLLARS>', 'amount of anchor tokens to give', Number)
163
- .option('--giveMinted <DOLLARS>', 'amount of minted tokens to give', Number)
164
- .option('--feePct [%]', 'Gas fee percentage', Number)
165
- .option('--offerId <string>', 'Offer id', String, `swap-${Date.now()}`)
166
- .action(
167
- async function (
168
- /** @type {Parameters<typeof Offers.psm.swap>[2]} */ opts,
169
- ) {
170
- console.warn('running with options', opts);
171
- const { agoricNames, lookupPsmInstance } = await rpcTools();
172
- const instance = await lookupPsmInstance(opts.pair);
173
- const offer = Offers.psm.swap(agoricNames, instance, opts);
174
- outputExecuteOfferAction(offer);
175
- },
176
- );
177
-
178
- psm
179
- .command('proposePauseOffers')
180
- .description('propose a vote')
181
- .option(
182
- '--offerId <string>',
183
- 'Offer id',
184
- String,
185
- `proposePauseOffers-${Date.now()}`,
186
- )
187
- .requiredOption(
188
- '--pair [Minted.Anchor]',
189
- 'token pair (Minted.Anchor)',
190
- s => s.split('.'),
191
- ['IST', 'AUSD'],
192
- )
193
- .requiredOption(
194
- '--charterAcceptOfferId <string>',
195
- 'offer that had continuing invitation result',
196
- )
197
- .requiredOption(
198
- '--substring <string>',
199
- 'an offer string to pause (can be repeated)',
200
- collectValues,
201
- [],
202
- )
203
- .option(
204
- '--deadline <minutes>',
205
- 'minutes from now to close the vote',
206
- Number,
207
- 1,
208
- )
209
- .action(async function (opts) {
210
- const { lookupPsmInstance } = await rpcTools();
211
- const psmInstance = lookupPsmInstance(opts.pair);
212
-
213
- /** @type {OfferSpec} */
214
- const offer = {
215
- id: opts.offerId,
216
- invitationSpec: {
217
- source: 'continuing',
218
- previousOffer: opts.charterAcceptOfferId,
219
- invitationMakerName: 'VoteOnPauseOffers',
220
- // ( instance, strings list, timer deadline seconds )
221
- invitationArgs: harden([
222
- psmInstance,
223
- opts.substring,
224
- BigInt(opts.deadline * 60 + Math.round(Date.now() / 1000)),
225
- ]),
226
- },
227
- proposal: {},
228
- };
229
-
230
- outputExecuteOfferAction(offer);
231
- });
232
-
233
- psm
234
- .command('proposeChangeMintLimit')
235
- .description('propose to change the MintLimit parameter')
236
- .option(
237
- '--offerId <string>',
238
- 'id of this offer (optional)',
239
- String,
240
- `proposeChangeMintLimit-${Date.now()}`,
241
- )
242
- .requiredOption(
243
- '--pair [Minted.Anchor]',
244
- 'token pair (Minted.Anchor)',
245
- s => s.split('.'),
246
- ['IST', 'AUSD'],
247
- )
248
- .requiredOption(
249
- '--previousOfferId <string>',
250
- 'offer using psm charter invitation',
251
- )
252
- .requiredOption('--limit <number>', 'new mint limit (in IST)', Number)
253
- .option(
254
- '--deadline <minutes>',
255
- 'minutes from now to close the vote',
256
- Number,
257
- 1,
258
- )
259
- .action(async function (opts) {
260
- const { agoricNames, lookupPsmInstance } = await rpcTools();
261
- const psmInstance = lookupPsmInstance(opts.pair);
262
-
263
- const istBrand = agoricNames.brand.IST;
264
- const scaledAmount = harden({
265
- brand: istBrand,
266
- value: BigInt(opts.limit * 1_000_000),
267
- });
268
- /** @type {OfferSpec} */
269
- const offer = {
270
- id: opts.offerId,
271
- invitationSpec: {
272
- source: 'continuing',
273
- previousOffer: opts.previousOfferId,
274
- invitationMakerName: 'VoteOnParamChange',
275
- },
276
- proposal: {},
277
- offerArgs: {
278
- instance: psmInstance,
279
- params: { MintLimit: scaledAmount },
280
- deadline: BigInt(opts.deadline * 60 + Math.round(Date.now() / 1000)),
281
- },
282
- };
283
-
284
- outputExecuteOfferAction(offer);
285
- });
286
-
287
- return psm;
288
- };
@@ -1,110 +0,0 @@
1
- // @ts-check
2
- /* eslint-disable func-names */
3
- /* eslint-env node */
4
- import {
5
- fetchEnvNetworkConfig,
6
- makeAgoricNames,
7
- makeVstorageKit,
8
- } from '@agoric/client-utils';
9
- import { Offers } from '@agoric/inter-protocol/src/clientSupport.js';
10
- import { Command } from 'commander';
11
- import { outputActionAndHint } from '../lib/wallet.js';
12
-
13
- /**
14
- * @import {Logger} from '@agoric/internal/vendor/anylogger.js';
15
- * @import {OfferSpec} from '@agoric/smart-wallet/src/offers.js';
16
- */
17
-
18
- const networkConfig = await fetchEnvNetworkConfig({ env: process.env, fetch });
19
-
20
- /**
21
- * @param {Logger} _logger
22
- * @param {*} io
23
- */
24
- export const makeReserveCommand = (_logger, io = {}) => {
25
- const { stdout = process.stdout, stderr = process.stderr, now } = io;
26
- const reserve = new Command('reserve').description('Asset Reserve commands');
27
-
28
- reserve
29
- .command('add')
30
- .description('add collateral to the reserve')
31
- .requiredOption('--give <number>', 'Collateral to give', Number)
32
- .option('--collateral-brand <string>', 'Collateral brand key', 'ATOM')
33
- .option('--offer-id <string>', 'Offer id', String, `addCollateral-${now()}`)
34
- .action(
35
- /**
36
- * @param {{
37
- * give: number,
38
- * collateralBrand: string,
39
- * offerId: string,
40
- * }} opts
41
- */
42
- async ({ collateralBrand, ...opts }) => {
43
- const vsk = makeVstorageKit({ fetch }, networkConfig);
44
- const agoricNames = await makeAgoricNames(vsk.fromBoard, vsk.vstorage);
45
-
46
- const offer = Offers.reserve.AddCollateral(agoricNames, {
47
- collateralBrandKey: collateralBrand,
48
- ...opts,
49
- });
50
- outputActionAndHint(
51
- { method: 'executeOffer', offer },
52
- { stdout, stderr },
53
- );
54
- },
55
- );
56
-
57
- reserve
58
- .command('proposeBurn')
59
- .description('propose a call to burnFeesToReduceShortfall')
60
- .option(
61
- '--offerId <string>',
62
- 'Offer id',
63
- String,
64
- `proposePauseOffers-${Date.now()}`,
65
- )
66
- .requiredOption(
67
- '--charterAcceptOfferId <string>',
68
- 'offer that had continuing invitation result',
69
- )
70
- .requiredOption('--value [integer]', 'value of µIST to burn', BigInt)
71
- .option(
72
- '--deadline <minutes>',
73
- 'minutes from now to close the vote',
74
- Number,
75
- 1,
76
- )
77
- .action(async function (opts) {
78
- const vsk = makeVstorageKit({ fetch }, networkConfig);
79
- const agoricNames = await makeAgoricNames(vsk.fromBoard, vsk.vstorage);
80
-
81
- const reserveInstance = agoricNames.instance.reserve;
82
- assert(reserveInstance, 'missing reserve in names');
83
-
84
- const feesToBurn = { brand: agoricNames.brand.IST, value: opts.value };
85
-
86
- /** @type {OfferSpec} */
87
- const offer = {
88
- id: opts.offerId,
89
- invitationSpec: {
90
- source: 'continuing',
91
- previousOffer: opts.charterAcceptOfferId,
92
- invitationMakerName: 'VoteOnApiCall',
93
- invitationArgs: harden([
94
- reserveInstance,
95
- 'burnFeesToReduceShortfall',
96
- [feesToBurn],
97
- BigInt(opts.deadline * 60 + Math.round(Date.now() / 1000)),
98
- ]),
99
- },
100
- proposal: {},
101
- };
102
-
103
- outputActionAndHint(
104
- { method: 'executeOffer', offer },
105
- { stdout, stderr },
106
- );
107
- });
108
-
109
- return reserve;
110
- };
@@ -1,178 +0,0 @@
1
- // @ts-check
2
- /* eslint-disable func-names */
3
- /* eslint-env node */
4
- import {
5
- fetchEnvNetworkConfig,
6
- makeAgoricNames,
7
- makeVstorageKit,
8
- } from '@agoric/client-utils';
9
- import {
10
- lookupOfferIdForVault,
11
- Offers,
12
- } from '@agoric/inter-protocol/src/clientSupport.js';
13
- import { Command } from 'commander';
14
- import { normalizeAddressWithOptions } from '../lib/chain.js';
15
- import { getCurrent, outputExecuteOfferAction } from '../lib/wallet.js';
16
-
17
- /**
18
- * @import {Logger} from '@agoric/internal/vendor/anylogger.js';
19
- */
20
-
21
- const networkConfig = await fetchEnvNetworkConfig({ env: process.env, fetch });
22
-
23
- /**
24
- * @param {Logger} logger
25
- */
26
- export const makeVaultsCommand = logger => {
27
- const vaults = new Command('vaults')
28
- .description('Vault Factory commands')
29
- .option('--home [dir]', 'agd application home directory')
30
- .option(
31
- '--keyring-backend <os|file|test>',
32
- 'keyring\'s backend (os|file|test) (default "os")',
33
- );
34
-
35
- const normalizeAddress = literalOrName =>
36
- normalizeAddressWithOptions(literalOrName, vaults.opts());
37
-
38
- vaults
39
- .command('list')
40
- .description(
41
- 'list vaults ever owned by the address (as path that can be followed)',
42
- )
43
- .requiredOption(
44
- '--from <address>',
45
- 'wallet address literal or name',
46
- normalizeAddress,
47
- )
48
- .action(async function (opts) {
49
- const { readPublished } = await makeVstorageKit({ fetch }, networkConfig);
50
-
51
- const current = await getCurrent(opts.from, {
52
- readPublished,
53
- });
54
-
55
- const vaultStoragePaths = current.offerToPublicSubscriberPaths.map(
56
- ([_offerId, pathmap]) => pathmap.vault,
57
- );
58
-
59
- for (const path of vaultStoragePaths) {
60
- process.stdout.write(path);
61
- process.stdout.write('\n');
62
- }
63
- });
64
-
65
- vaults
66
- .command('open')
67
- .description('Prepare an offer to open a new vault')
68
- .requiredOption('--giveCollateral <number>', 'Collateral to give', Number)
69
- .requiredOption('--wantMinted <number>', 'Minted wants', Number)
70
- .option('--offerId <string>', 'Offer id', String, `openVault-${Date.now()}`)
71
- .option('--collateralBrand <string>', 'Collateral brand key', 'ATOM')
72
- .action(async function (opts) {
73
- logger.warn('running with options', opts);
74
- const vsk = makeVstorageKit({ fetch }, networkConfig);
75
- const agoricNames = await makeAgoricNames(vsk.fromBoard, vsk.vstorage);
76
-
77
- const offer = Offers.vaults.OpenVault(agoricNames, {
78
- giveCollateral: opts.giveCollateral,
79
- wantMinted: opts.wantMinted,
80
- offerId: opts.offerId,
81
- // rename to allow CLI to be more concise
82
- collateralBrandKey: opts.collateralBrand,
83
- });
84
-
85
- outputExecuteOfferAction(offer);
86
- });
87
-
88
- vaults
89
- .command('adjust')
90
- .description('Prepare an offer to adjust an existing vault')
91
- .requiredOption(
92
- '--from <address>',
93
- 'wallet address literal or name',
94
- normalizeAddress,
95
- )
96
- .option('--giveCollateral <number>', 'More collateral to lend', Number)
97
- .option('--wantCollateral <number>', 'Collateral to get back', Number)
98
- .option('--giveMinted <number>', 'Minted to give back', Number)
99
- .option('--wantMinted <number>', 'More minted to borrow', Number)
100
- .option(
101
- '--offerId <string>',
102
- 'Offer id',
103
- String,
104
- `adjustVault-${Date.now()}`,
105
- )
106
- .option('--collateralBrand <string>', 'Collateral brand key', 'ATOM')
107
- .requiredOption('--vaultId <string>', 'Key of vault (e.g. vault1)')
108
- .action(async function (opts) {
109
- logger.warn('running with options', opts);
110
- const { readPublished, ...vsk } = makeVstorageKit(
111
- { fetch },
112
- networkConfig,
113
- );
114
- const agoricNames = await makeAgoricNames(vsk.fromBoard, vsk.vstorage);
115
-
116
- const previousOfferId = await lookupOfferIdForVault(
117
- opts.vaultId,
118
- getCurrent(opts.from, { readPublished }),
119
- );
120
-
121
- const offer = Offers.vaults.AdjustBalances(
122
- agoricNames,
123
- {
124
- giveCollateral: opts.giveCollateral,
125
- wantCollateral: opts.wantCollateral,
126
- giveMinted: opts.giveMinted,
127
- wantMinted: opts.wantMinted,
128
- offerId: opts.offerId,
129
- // rename to allow CLI to be more concise
130
- collateralBrandKey: opts.collateralBrand,
131
- },
132
- previousOfferId,
133
- );
134
- outputExecuteOfferAction(offer);
135
- });
136
-
137
- vaults
138
- .command('close')
139
- .description('Prepare an offer to close an existing vault')
140
- .requiredOption(
141
- '--from <address>',
142
- 'wallet address literal or name',
143
- normalizeAddress,
144
- )
145
- .requiredOption('--giveMinted <number>', 'Minted to give back', Number)
146
- .requiredOption('--vaultId <string>', 'Key of vault (e.g. vault1)')
147
- .option(
148
- '--offerId <string>',
149
- 'Offer id',
150
- String,
151
- `closeVault-${Date.now()}`,
152
- )
153
- .action(async function (opts) {
154
- logger.warn('running with options', opts);
155
- const { readPublished, ...vsk } = makeVstorageKit(
156
- { fetch },
157
- networkConfig,
158
- );
159
- const agoricNames = await makeAgoricNames(vsk.fromBoard, vsk.vstorage);
160
-
161
- const previousOfferId = await lookupOfferIdForVault(
162
- opts.vaultId,
163
- getCurrent(opts.from, { readPublished }),
164
- );
165
-
166
- const offer = Offers.vaults.CloseVault(
167
- agoricNames,
168
- {
169
- giveMinted: opts.giveMinted,
170
- offerId: opts.offerId,
171
- },
172
- previousOfferId,
173
- );
174
- outputExecuteOfferAction(offer);
175
- });
176
-
177
- return vaults;
178
- };