agoric 0.21.2-other-dev-fbe72e7.0.fbe72e7 → 0.21.2-other-dev-d15096d.0.d15096d

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-other-dev-fbe72e7.0.fbe72e7",
3
+ "version": "0.21.2-other-dev-d15096d.0.d15096d",
4
4
  "description": "Manage the Agoric Javascript smart contract platform",
5
5
  "type": "module",
6
6
  "main": "src/main.js",
@@ -30,28 +30,28 @@
30
30
  "lint:eslint": "yarn run -T eslint ."
31
31
  },
32
32
  "devDependencies": {
33
- "@agoric/cosmic-swingset": "0.41.4-other-dev-fbe72e7.0.fbe72e7",
34
- "@agoric/deploy-script-support": "0.10.4-other-dev-fbe72e7.0.fbe72e7",
33
+ "@agoric/cosmic-swingset": "0.41.4-other-dev-d15096d.0.d15096d",
34
+ "@agoric/deploy-script-support": "0.10.4-other-dev-d15096d.0.d15096d",
35
35
  "ava": "^5.3.0",
36
36
  "c8": "^10.1.2"
37
37
  },
38
38
  "dependencies": {
39
- "@agoric/access-token": "0.4.22-other-dev-fbe72e7.0.fbe72e7",
40
- "@agoric/cache": "0.3.3-other-dev-fbe72e7.0.fbe72e7",
41
- "@agoric/casting": "0.4.3-other-dev-fbe72e7.0.fbe72e7",
42
- "@agoric/client-utils": "0.1.1-other-dev-fbe72e7.0.fbe72e7",
43
- "@agoric/cosmic-proto": "0.4.1-other-dev-fbe72e7.0.fbe72e7",
44
- "@agoric/ertp": "0.16.3-other-dev-fbe72e7.0.fbe72e7",
45
- "@agoric/governance": "0.10.4-other-dev-fbe72e7.0.fbe72e7",
46
- "@agoric/inter-protocol": "0.16.2-other-dev-fbe72e7.0.fbe72e7",
47
- "@agoric/internal": "0.3.3-other-dev-fbe72e7.0.fbe72e7",
48
- "@agoric/network": "0.1.1-other-dev-fbe72e7.0.fbe72e7",
49
- "@agoric/smart-wallet": "0.5.4-other-dev-fbe72e7.0.fbe72e7",
50
- "@agoric/store": "0.9.3-other-dev-fbe72e7.0.fbe72e7",
51
- "@agoric/swingset-vat": "0.32.3-other-dev-fbe72e7.0.fbe72e7",
52
- "@agoric/vats": "0.15.2-other-dev-fbe72e7.0.fbe72e7",
53
- "@agoric/zoe": "0.26.3-other-dev-fbe72e7.0.fbe72e7",
54
- "@agoric/zone": "0.2.3-other-dev-fbe72e7.0.fbe72e7",
39
+ "@agoric/access-token": "0.4.22-other-dev-d15096d.0.d15096d",
40
+ "@agoric/cache": "0.3.3-other-dev-d15096d.0.d15096d",
41
+ "@agoric/casting": "0.4.3-other-dev-d15096d.0.d15096d",
42
+ "@agoric/client-utils": "0.1.1-other-dev-d15096d.0.d15096d",
43
+ "@agoric/cosmic-proto": "0.4.1-other-dev-d15096d.0.d15096d",
44
+ "@agoric/ertp": "0.16.3-other-dev-d15096d.0.d15096d",
45
+ "@agoric/governance": "0.10.4-other-dev-d15096d.0.d15096d",
46
+ "@agoric/inter-protocol": "0.16.2-other-dev-d15096d.0.d15096d",
47
+ "@agoric/internal": "0.3.3-other-dev-d15096d.0.d15096d",
48
+ "@agoric/network": "0.1.1-other-dev-d15096d.0.d15096d",
49
+ "@agoric/smart-wallet": "0.5.4-other-dev-d15096d.0.d15096d",
50
+ "@agoric/store": "0.9.3-other-dev-d15096d.0.d15096d",
51
+ "@agoric/swingset-vat": "0.32.3-other-dev-d15096d.0.d15096d",
52
+ "@agoric/vats": "0.15.2-other-dev-d15096d.0.d15096d",
53
+ "@agoric/zoe": "0.26.3-other-dev-d15096d.0.d15096d",
54
+ "@agoric/zone": "0.2.3-other-dev-d15096d.0.d15096d",
55
55
  "@cosmjs/crypto": "^0.36.0",
56
56
  "@cosmjs/encoding": "^0.36.0",
57
57
  "@cosmjs/math": "^0.36.0",
@@ -99,10 +99,10 @@
99
99
  "workerThreads": false
100
100
  },
101
101
  "typeCoverage": {
102
- "atLeast": 79.88
102
+ "atLeast": 79.84
103
103
  },
104
104
  "engines": {
105
105
  "node": "^20.9 || ^22.11"
106
106
  },
107
- "gitHead": "fbe72e72107f9997f788674e668c660d92ec4492"
107
+ "gitHead": "d15096dc4ff8b96e9b6cd11954c20d3a9efbb393"
108
108
  }
package/src/bin-agops.js CHANGED
@@ -19,7 +19,6 @@ import { makeReserveCommand } from './commands/reserve.js';
19
19
  import { makeVaultsCommand } from './commands/vaults.js';
20
20
  import { makePerfCommand } from './commands/perf.js';
21
21
  import { makeInterCommand } from './commands/inter.js';
22
- import { makeAuctionCommand } from './commands/auction.js';
23
22
  import { makeTestCommand } from './commands/test-upgrade.js';
24
23
 
25
24
  const logger = anylogger('agops');
@@ -68,7 +67,6 @@ const procIO = {
68
67
 
69
68
  program.addCommand(makeOracleCommand(procIO, logger));
70
69
  program.addCommand(makeReserveCommand(logger, procIO));
71
- program.addCommand(makeAuctionCommand(logger, { ...procIO, fetch }));
72
70
  program.addCommand(makeInterCommand(procIO, { fetch }));
73
71
  program.addCommand(makeTestCommand(procIO, { fetch }));
74
72
 
@@ -22,6 +22,8 @@ import {
22
22
  * @import {AgoricNamesRemotes} from '@agoric/vats/tools/board-utils.js';
23
23
  * @import {CurrentWalletRecord} from '@agoric/smart-wallet/src/smartWallet.js';
24
24
  * @import {VstorageKit} from '@agoric/client-utils';
25
+ * @import {Logger} from 'anylogger';
26
+ * @import {Writable} from 'stream';
25
27
  */
26
28
 
27
29
  const collectValues = (val, memo) => {
@@ -34,12 +36,12 @@ const defaultKeyring = process.env.AGORIC_KEYRING_BACKEND || 'test';
34
36
  const networkConfig = await fetchEnvNetworkConfig({ env: process.env, fetch });
35
37
 
36
38
  /**
37
- * @param {import('anylogger').Logger} _logger
39
+ * @param {Logger} _logger
38
40
  * @param {{
39
41
  * env?: Record<string, string|undefined>,
40
42
  * fetch?: typeof window.fetch,
41
- * stdout?: Pick<import('stream').Writable, 'write'>,
42
- * stderr?: Pick<import('stream').Writable, 'write'>,
43
+ * stdout?: Pick<Writable, 'write'>,
44
+ * stderr?: Pick<Writable, 'write'>,
43
45
  * execFileSync?: typeof execFileSyncAmbient,
44
46
  * delay?: (ms: number) => Promise<void>,
45
47
  * }} [io]
@@ -5,189 +5,36 @@
5
5
 
6
6
  // @ts-check
7
7
  import { fetchEnvNetworkConfig, makeWalletUtils } from '@agoric/client-utils';
8
- import { makeOfferSpecShape } from '@agoric/inter-protocol/src/auction/auctionBook.js';
9
- import { Offers } from '@agoric/inter-protocol/src/clientSupport.js';
10
- import { objectMap } from '@agoric/internal';
11
- import { M, matches } from '@endo/patterns';
12
- import { CommanderError, InvalidArgumentError } from 'commander';
13
- import { normalizeAddressWithOptions, pollBlocks } from '../lib/chain.js';
14
- import {
15
- asBoardRemote,
16
- bigintReplacer,
17
- makeAmountFormatter,
18
- } from '../lib/format.js';
19
- import { getCurrent, outputActionAndHint, sendAction } from '../lib/wallet.js';
20
-
21
- const { values } = Object;
22
-
23
- const bidInvitationShape = harden({
24
- source: 'agoricContract',
25
- instancePath: ['auctioneer'],
26
- callPipe: [['makeBidInvitation', M.any()]],
27
- });
28
-
29
- /** @import {VBankAssetDetail} from '@agoric/vats/tools/board-utils.js'; */
30
- /** @import {TryExitOfferAction} from '@agoric/smart-wallet/src/smartWallet.js'; */
31
- /** @import {OfferSpec as BidSpec} from '@agoric/inter-protocol/src/auction/auctionBook.js' */
32
- /** @import {ScheduleNotification} from '@agoric/inter-protocol/src/auction/scheduler.js' */
33
- /** @import {BookDataNotification} from '@agoric/inter-protocol/src/auction/auctionBook.js' */
8
+ import { CommanderError } from 'commander';
9
+ import { bigintReplacer } from '../lib/format.js';
34
10
 
35
11
  /**
36
- * Format amounts, prices etc. based on brand board Ids, displayInfo
37
- *
38
- * @param {VBankAssetDetail[]} assets
12
+ * @import {VBankAssetDetail} from '@agoric/vats/tools/board-utils.js';
13
+ * @import {Timestamp} from '@agoric/time';
14
+ * @import {RelativeTimeRecord} from '@agoric/time';
15
+ * @import {OfferStatus} from '@agoric/smart-wallet/src/offers.js';
16
+ * @import {Writable} from 'stream';
17
+ * @import {createCommand} from 'commander';
18
+ * @import {execFileSync} from 'child_process';
39
19
  */
40
- const makeFormatters = assets => {
41
- const r4 = x => Math.round(x * 10_000) / 10_000;
42
-
43
- const br = asBoardRemote;
44
- const fmtAmtTuple = makeAmountFormatter(assets);
45
-
46
- /** @param {Amount} amt */
47
- const amount = amt => (([l, m]) => `${m} ${l}`)(fmtAmtTuple(br(amt)));
48
- /** @param {Record<string, Amount> | undefined} r */
49
- const record = r => (r ? objectMap(r, amount) : undefined);
50
- /** @param {Ratio} r */
51
- const price = r => {
52
- const [nl, nm] = fmtAmtTuple(br(r.numerator));
53
- const [dl, dm] = fmtAmtTuple(br(r.denominator));
54
- return `${r4(Number(nm) / Number(dm))} ${nl}/${dl}`;
55
- };
56
- /** @param {Ratio} r */
57
- const discount = r =>
58
- r4(100 - (Number(r.numerator.value) / Number(r.denominator.value)) * 100);
59
-
60
- // XXX real TimeMath.absValue requires real Remotable timerBrand
61
- /** @param {import('@agoric/time').Timestamp} ts */
62
- const absValue = ts => (typeof ts === 'bigint' ? ts : ts.absValue);
63
-
64
- /** @param {import('@agoric/time').Timestamp} tr */
65
- const absTime = tr => new Date(Number(absValue(tr)) * 1000).toISOString();
66
- /** @param {import('@agoric/time').RelativeTimeRecord} tr */
67
- const relTime = tr =>
68
- new Date(Number(tr.relValue) * 1000).toISOString().slice(11, 19);
69
-
70
- /** @param {bigint} bp */
71
- const basisPoints = bp => `${(Number(bp) / 100).toFixed(2)}%`;
72
-
73
- /**
74
- * @template T
75
- * @param {(_: T) => string} f
76
- * @returns { (x: T | null | undefined ) => string | undefined }
77
- */
78
- const maybe = f => x => (x ? f(x) : undefined);
79
-
80
- return {
81
- amount,
82
- amountOpt: maybe(amount),
83
- record,
84
- price,
85
- priceOpt: maybe(price),
86
- discount,
87
- absTime,
88
- absTimeOpt: maybe(absTime),
89
- relTime,
90
- basisPoints,
91
- };
92
- };
93
20
 
94
21
  /**
95
- * Dynamic check that an OfferStatus is also a BidSpec.
96
- *
97
- * @param {import('@agoric/smart-wallet/src/offers.js').OfferStatus} offerStatus
98
- * @param {import('@agoric/vats/tools/board-utils.js').AgoricNamesRemotes} agoricNames
99
- * @param {typeof console.warn} warn
100
- * returns null if offerStatus is not a BidSpec
101
- */
102
- const coerceBid = (offerStatus, agoricNames, warn) => {
103
- const { offerArgs } = offerStatus;
104
- /** @type {unknown} */
105
- const collateralBrand = /** @type {any} */ (offerArgs)?.maxBuy?.brand;
106
- if (!collateralBrand) {
107
- warn('mal-formed bid offerArgs', offerStatus.id, offerArgs);
108
- return null;
109
- }
110
- const bidSpecShape = makeOfferSpecShape(
111
- // @ts-expect-error XXX AssetKind narrowing?
112
- agoricNames.brand.IST,
113
- collateralBrand,
114
- );
115
- if (!matches(offerStatus.offerArgs, bidSpecShape)) {
116
- warn('mal-formed bid offerArgs', offerArgs);
117
- return null;
118
- }
119
-
120
- /**
121
- * @type {import('@agoric/smart-wallet/src/offers.js').OfferStatus &
122
- * { offerArgs: BidSpec}}
123
- */
124
- // @ts-expect-error dynamic cast
125
- const bid = offerStatus;
126
- return bid;
127
- };
128
-
129
- /**
130
- * Format amounts etc. in a BidSpec OfferStatus
131
- *
132
- * @param {import('@agoric/smart-wallet/src/offers.js').OfferStatus &
133
- * { offerArgs: BidSpec}} bid
134
- * @param {VBankAssetDetail[]} assets
135
- */
136
- export const fmtBid = (bid, assets) => {
137
- const fmt = makeFormatters(assets);
138
-
139
- const { offerArgs } = bid;
140
- /** @type {{ price: string } | { discount: number }} */
141
- const spec =
142
- 'offerPrice' in offerArgs
143
- ? { price: fmt.price(offerArgs.offerPrice) }
144
- : { discount: fmt.discount(offerArgs.offerBidScaling) };
145
-
146
- const {
147
- id,
148
- proposal: { give, want },
149
- offerArgs: { maxBuy },
150
- payouts,
151
- result,
152
- error,
153
- } = bid;
154
- const resultProp =
155
- !error && result && result !== 'UNPUBLISHED' ? { result } : {};
156
- const props = {
157
- ...(give ? { give: fmt.record(give) } : {}),
158
- ...(want ? { give: fmt.record(want) } : {}),
159
- ...(maxBuy ? { maxBuy: fmt.amount(maxBuy) } : {}),
160
- ...(payouts ? { payouts: fmt.record(payouts) } : resultProp),
161
- ...(error ? { error } : {}),
162
- };
163
- return harden({ id, ...spec, ...props });
164
- };
165
-
166
- /**
167
- * Make Inter Protocol liquidation bidding commands.
22
+ * Make Inter Protocol commands.
168
23
  *
169
24
  * @param {{
170
25
  * env: Partial<Record<string, string>>,
171
- * stdout: Pick<import('stream').Writable,'write'>,
172
- * stderr: Pick<import('stream').Writable,'write'>,
26
+ * stdout: Pick<Writable,'write'>,
27
+ * stderr: Pick<Writable,'write'>,
173
28
  * now: () => number,
174
29
  * createCommand: // Note: includes access to process.stdout, .stderr, .exit
175
- * typeof import('commander').createCommand,
176
- * execFileSync: typeof import('child_process').execFileSync,
30
+ * typeof createCommand,
31
+ * execFileSync: typeof execFileSync,
177
32
  * setTimeout: typeof setTimeout,
178
33
  * }} process
179
34
  * @param {{ fetch: typeof window.fetch }} net
180
35
  */
181
36
  export const makeInterCommand = (
182
- {
183
- env,
184
- stdout,
185
- stderr,
186
- now,
187
- setTimeout,
188
- execFileSync: rawExec,
189
- createCommand,
190
- },
37
+ { env, stdout, setTimeout, createCommand },
191
38
  { fetch },
192
39
  ) => {
193
40
  const interCmd = createCommand('inter')
@@ -205,20 +52,6 @@ export const makeInterCommand = (
205
52
  env.AGORIC_KEYRING_BACKEND,
206
53
  );
207
54
 
208
- /** @type {typeof import('child_process').execFileSync} */
209
- // @ts-expect-error execFileSync is overloaded
210
- const execFileSync = (file, args, ...opts) => {
211
- try {
212
- return rawExec(file, args, ...opts);
213
- } catch (err) {
214
- // InvalidArgumentError is a class constructor, and so
215
- // must be invoked with `new`.
216
- throw new InvalidArgumentError(
217
- `${err.message}: is ${file} in your $PATH?`,
218
- );
219
- }
220
- };
221
-
222
55
  /** @param {number} ms */
223
56
  const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
224
57
  const show = (info, indent = false) =>
@@ -240,351 +73,6 @@ export const makeInterCommand = (
240
73
  }
241
74
  };
242
75
 
243
- const auctionCmd = interCmd
244
- .command('auction')
245
- .description('auction commands');
246
- auctionCmd
247
- .command('status')
248
- .description(
249
- `show auction status in JSON format
250
-
251
- For example:
252
-
253
- inter auction status
254
- {
255
- "schedule": {
256
- "activeStartTime": "2023-04-19T22:50:02.000Z",
257
- "nextStartTime": "2023-04-19T23:00:02.000Z",
258
- "nextDescendingStepTime": "2023-04-19T22:51:02.000Z"
259
- },
260
- "book0": {
261
- "startPrice": "12.34 IST/ATOM",
262
- "currentPriceLevel": "11.723 IST/ATOM",
263
- "startCollateral": "0 ATOM",
264
- "collateralAvailable": "0 ATOM"
265
- },
266
- "params": {
267
- "DiscountStep": "5.00%",
268
- "ClockStep": "00:00:20",
269
- "LowestRate": "45.00%"
270
- }
271
- }
272
- `,
273
- )
274
- .option('--book <number>', 'Auction Book', Number, 0)
275
- .action(
276
- async (
277
- /**
278
- * @type {{
279
- * book: number,
280
- * }}
281
- */ opts,
282
- ) => {
283
- const { agoricNames, readPublished } = await tryMakeUtils();
284
-
285
- const [schedule, book, { current: params }] = await Promise.all([
286
- readPublished('auction.schedule'),
287
- readPublished(`auction.book${opts.book}`),
288
- readPublished('auction.governance'),
289
- ]);
290
-
291
- const fmt = makeFormatters(Object.values(agoricNames.vbankAsset));
292
- const info = {
293
- schedule: {
294
- activeStartTime: fmt.absTimeOpt(schedule.activeStartTime),
295
- nextStartTime: fmt.absTimeOpt(schedule.nextStartTime),
296
- nextDescendingStepTime: fmt.absTimeOpt(
297
- schedule.nextDescendingStepTime,
298
- ),
299
- },
300
- [`book${opts.book}`]: {
301
- startPrice: fmt.priceOpt(book.startPrice),
302
- currentPriceLevel: fmt.priceOpt(book.currentPriceLevel),
303
- startProceedsGoal: fmt.amountOpt(book.startProceedsGoal),
304
- remainingProceedsGoal: fmt.amountOpt(book.remainingProceedsGoal),
305
- proceedsRaised: fmt.amountOpt(book.proceedsRaised),
306
- startCollateral: fmt.amount(book.startCollateral),
307
- collateralAvailable: fmt.amountOpt(book.collateralAvailable),
308
- },
309
- params: {
310
- DiscountStep: fmt.basisPoints(params.DiscountStep.value),
311
- ClockStep: fmt.relTime(params.ClockStep.value),
312
- LowestRate: fmt.basisPoints(params.LowestRate.value),
313
- },
314
- };
315
-
316
- show(info, true);
317
- },
318
- );
319
-
320
- const bidCmd = interCmd
321
- .command('bid')
322
- .description('auction bidding commands');
323
-
324
- /**
325
- * @param {string} from
326
- * @param {import('@agoric/smart-wallet/src/offers.js').OfferSpec} offer
327
- * @param {Awaited<ReturnType<tryMakeUtils>>} tools
328
- * @param {boolean | undefined} dryRun
329
- */
330
- const placeBid = async (from, offer, tools, dryRun = false) => {
331
- const { networkConfig, agoricNames, pollOffer } = tools;
332
- const io = { ...networkConfig, execFileSync, delay, stdout };
333
-
334
- const { home, keyringBackend: backend, fees } = interCmd.opts();
335
- const result = await sendAction(
336
- { method: 'executeOffer', offer },
337
- { keyring: { home, backend }, from, fees, verbose: false, dryRun, ...io },
338
- );
339
- if (dryRun) {
340
- return;
341
- }
342
-
343
- assert(result); // Not dry-run
344
- const { timestamp, txhash, height } = result;
345
- console.error('bid is broadcast:');
346
- show({ timestamp, height, offerId: offer.id, txhash });
347
- const found = await pollOffer(from, offer.id, height);
348
- // TODO: command to wait 'till bid exits?
349
- const bid = coerceBid(found, agoricNames, console.warn);
350
- if (!bid) {
351
- console.warn('malformed bid', found);
352
- return;
353
- }
354
- const info = fmtBid(bid, values(agoricNames.vbankAsset));
355
- show(info);
356
- };
357
-
358
- /** @param {string} literalOrName */
359
- const normalizeAddress = literalOrName =>
360
- normalizeAddressWithOptions(literalOrName, interCmd.opts(), {
361
- execFileSync,
362
- });
363
-
364
- /**
365
- * @typedef {{
366
- * give: string,
367
- * maxBuy: string,
368
- * wantMinimum?: string,
369
- * offerId: string,
370
- * from: string,
371
- * generateOnly?: boolean,
372
- * dryRun?: boolean,
373
- * }} SharedBidOpts
374
- */
375
-
376
- /** @param {ReturnType<createCommand>} cmd */
377
- const withSharedBidOptions = cmd =>
378
- cmd
379
- .requiredOption(
380
- '--from <address>',
381
- 'wallet address literal or name',
382
- normalizeAddress,
383
- )
384
- .requiredOption('--give <amount>', 'IST to bid')
385
- .option(
386
- '--maxBuy <amount>',
387
- 'max Collateral wanted',
388
- String,
389
- '1_000_000ATOM',
390
- )
391
- .option(
392
- '--wantMinimum <amount>',
393
- 'only transact a bid that supplies this much collateral',
394
- )
395
- .option('--offer-id <string>', 'Offer id', String, `bid-${now()}`)
396
- .option('--generate-only', 'print wallet action only')
397
- .option('--dry-run', 'dry run only');
398
-
399
- withSharedBidOptions(bidCmd.command('by-price'))
400
- .description('Place a bid on collateral by price.')
401
- .requiredOption('--price <number>', 'bid price (IST/Collateral)', Number)
402
- .action(
403
- /**
404
- * @param {SharedBidOpts & {
405
- * price: number,
406
- * }} opts
407
- */
408
- async ({ generateOnly, dryRun, ...opts }) => {
409
- const tools = await tryMakeUtils();
410
-
411
- const offer = Offers.auction.Bid(tools.agoricNames, opts);
412
-
413
- if (generateOnly) {
414
- outputActionAndHint(
415
- { method: 'executeOffer', offer },
416
- { stdout, stderr },
417
- );
418
- return;
419
- }
420
-
421
- await placeBid(opts.from, offer, tools, dryRun);
422
- },
423
- );
424
-
425
- /** @param {string} v */
426
- const parsePercent = v => {
427
- const p = Number(v);
428
- if (!(p >= -100 && p <= 100)) {
429
- // InvalidArgumentError is a class constructor, and so
430
- // must be invoked with `new`.
431
- throw new InvalidArgumentError('must be between -100 and 100');
432
- }
433
- return p / 100;
434
- };
435
-
436
- withSharedBidOptions(bidCmd.command('by-discount'))
437
- .description(
438
- `Place a bid on collateral based on discount from oracle price.`,
439
- )
440
- .requiredOption(
441
- '--discount <percent>',
442
- 'bid discount (0 to 100) or markup (0 to -100) %',
443
- parsePercent,
444
- )
445
- .action(
446
- /**
447
- * @param {SharedBidOpts & {
448
- * discount: number,
449
- * }} opts
450
- */
451
- async ({ generateOnly, ...opts }) => {
452
- const tools = await tryMakeUtils();
453
-
454
- const offer = Offers.auction.Bid(tools.agoricNames, opts);
455
- if (generateOnly) {
456
- outputActionAndHint(
457
- { method: 'executeOffer', offer },
458
- { stdout, stderr },
459
- );
460
- return;
461
- }
462
- await placeBid(opts.from, offer, tools);
463
- },
464
- );
465
-
466
- bidCmd
467
- .command('cancel')
468
- .description('Try to exit a bid offer')
469
- .argument('id', 'offer id (as from bid list)')
470
- .requiredOption(
471
- '--from <address>',
472
- 'wallet address literal or name',
473
- normalizeAddress,
474
- )
475
- .option('--generate-only', 'print wallet action only')
476
- .action(
477
- /**
478
- * @param {string} id
479
- * @param {{
480
- * from: string,
481
- * generateOnly?: boolean,
482
- * }} opts
483
- */
484
- async (id, { from, generateOnly }) => {
485
- /** @type {TryExitOfferAction} */
486
- const action = { method: 'tryExitOffer', offerId: id };
487
-
488
- if (generateOnly) {
489
- outputActionAndHint(action, { stdout, stderr });
490
- return;
491
- }
492
-
493
- const { networkConfig, readPublished } = await tryMakeUtils();
494
-
495
- const current = await getCurrent(from, { readPublished });
496
- const liveIds = current.liveOffers.map(([i, _s]) => i);
497
- if (!liveIds.includes(id)) {
498
- // InvalidArgumentError is a class constructor, and so
499
- // must be invoked with `new`.
500
- throw new InvalidArgumentError(
501
- `${id} not in live offer ids: ${liveIds}`,
502
- );
503
- }
504
-
505
- const io = { ...networkConfig, execFileSync, delay, stdout };
506
-
507
- const { home, keyringBackend: backend } = interCmd.opts();
508
- const result = await sendAction(action, {
509
- keyring: { home, backend },
510
- from,
511
- verbose: false,
512
- ...io,
513
- });
514
- assert(result); // not dry-run
515
- const { timestamp, txhash, height } = result;
516
- console.error('cancel action is broadcast:');
517
- show({ timestamp, height, offerId: id, txhash });
518
-
519
- const checkGone = async blockInfo => {
520
- const pollResult = await getCurrent(from, { readPublished });
521
- const found = pollResult.liveOffers.find(([i, _]) => i === id);
522
- if (found) throw Error('retry');
523
- return blockInfo;
524
- };
525
- const blockInfo = await pollBlocks({
526
- retryMessage: 'offer still live in block',
527
- ...networkConfig,
528
- execFileSync,
529
- delay,
530
- })(checkGone);
531
- console.error('bid', id, 'is no longer live');
532
- show(blockInfo);
533
- },
534
- );
535
-
536
- bidCmd
537
- .command('list')
538
- .description(
539
- `Show status of bid offers.
540
-
541
- For example:
542
-
543
- $ inter bid list --from my-acct
544
- {"id":"bid-1679677228803","price":"9 IST/ATOM","give":{"Bid":"50IST"},"want":"5ATOM"}
545
- {"id":"bid-1679677312341","discount":10,"give":{"Bid":"200IST"},"want":"1ATOM"}
546
- `,
547
- )
548
- .requiredOption(
549
- '--from <address>',
550
- 'wallet address literal or name',
551
- normalizeAddress,
552
- )
553
- .option('--all', 'show exited bids as well')
554
- .action(
555
- /**
556
- * @param {{
557
- * from: string,
558
- * all?: boolean,
559
- * }} opts
560
- */
561
- async opts => {
562
- const { agoricNames, readPublished, storedWalletState } =
563
- await tryMakeUtils();
564
-
565
- const [current, state] = await Promise.all([
566
- getCurrent(opts.from, { readPublished }),
567
- storedWalletState(opts.from),
568
- ]);
569
- const entries = opts.all
570
- ? state.offerStatuses.entries()
571
- : current.liveOffers;
572
- for (const [id, spec] of entries) {
573
- const offerStatus = state.offerStatuses.get(id) || spec;
574
- harden(offerStatus); // coalesceWalletState should do this
575
- // console.debug(offerStatus.invitationSpec);
576
- if (!matches(offerStatus.invitationSpec, bidInvitationShape))
577
- continue;
578
-
579
- const bid = coerceBid(offerStatus, agoricNames, console.warn);
580
- if (!bid) continue;
581
-
582
- const info = fmtBid(bid, values(agoricNames.vbankAsset));
583
- show(info);
584
- }
585
- },
586
- );
587
-
588
76
  const assetCmd = interCmd
589
77
  .command('vbank')
590
78
  .description('vbank asset commands');