agoric 0.18.4 → 0.18.5-dev-800c2bb.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/README.md +73 -0
- package/package.json +37 -30
- package/src/bin-agops.js +68 -6
- package/src/chain-config.js +19 -2
- package/src/commands/auction.js +170 -0
- package/src/commands/ec.js +314 -0
- package/src/commands/inter.js +626 -0
- package/src/commands/oracle.js +212 -0
- package/src/commands/perf.js +32 -22
- package/src/commands/psm.js +75 -210
- package/src/commands/reserve.js +98 -0
- package/src/commands/test-upgrade.js +109 -0
- package/src/commands/vaults.js +161 -0
- package/src/commands/wallet.js +85 -60
- package/src/cosmos.js +5 -9
- package/src/deploy.js +208 -334
- package/src/entrypoint.js +9 -2
- package/src/follow.js +40 -4
- package/src/init.js +11 -10
- package/src/install.js +25 -30
- package/src/json-http-client-node.js +2 -2
- package/src/json.js +1 -1
- package/src/lib/casting.js +4 -2
- package/src/lib/chain.js +147 -33
- package/src/lib/format.js +58 -43
- package/src/lib/rpc.js +106 -101
- package/src/lib/wallet.js +305 -10
- package/src/main-publish.js +3 -5
- package/src/main.js +74 -42
- package/src/open.js +3 -1
- package/src/publish.js +25 -23
- package/src/run.js +20 -0
- package/src/scripts.js +190 -0
- package/src/sdk-package-names.js +6 -2
- package/src/set-defaults.js +2 -2
- package/src/start.js +69 -35
- package/src/lib/psm.js +0 -82
package/src/commands/psm.js
CHANGED
|
@@ -4,13 +4,10 @@
|
|
|
4
4
|
/* eslint-disable func-names */
|
|
5
5
|
/* global fetch, process */
|
|
6
6
|
import { Command } from 'commander';
|
|
7
|
+
import { Offers } from '@agoric/inter-protocol/src/clientSupport.js';
|
|
7
8
|
import { asPercent } from '../lib/format.js';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
makeRpcUtils,
|
|
11
|
-
boardSlottingMarshaller,
|
|
12
|
-
storageHelper,
|
|
13
|
-
} from '../lib/rpc.js';
|
|
9
|
+
import { makeRpcUtils, storageHelper } from '../lib/rpc.js';
|
|
10
|
+
import { outputExecuteOfferAction } from '../lib/wallet.js';
|
|
14
11
|
|
|
15
12
|
// Adapted from https://gist.github.com/dckc/8b5b2f16395cb4d7f2ff340e0bc6b610#file-psm-tool
|
|
16
13
|
|
|
@@ -33,35 +30,15 @@ function collectValues(val, memo) {
|
|
|
33
30
|
return memo;
|
|
34
31
|
}
|
|
35
32
|
|
|
36
|
-
const { vstorage, fromBoard, agoricNames } = await makeRpcUtils({ fetch });
|
|
37
|
-
|
|
38
33
|
/**
|
|
39
|
-
*
|
|
40
|
-
* @param {[Minted: string, Anchor: string]} pair
|
|
41
|
-
*/
|
|
42
|
-
const getGovernanceState = async ([Minted, Anchor]) => {
|
|
43
|
-
const govContent = await vstorage.readLatest(
|
|
44
|
-
`published.psm.${Minted}.${Anchor}.governance`,
|
|
45
|
-
);
|
|
46
|
-
assert(govContent, 'no gov content');
|
|
47
|
-
const { current: governance } = last(
|
|
48
|
-
storageHelper.unserializeTxt(govContent, fromBoard),
|
|
49
|
-
);
|
|
50
|
-
const { [`psm.${Minted}.${Anchor}`]: instance } = agoricNames.instance;
|
|
51
|
-
|
|
52
|
-
return { instance, governance };
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
*
|
|
57
34
|
* @param {import('anylogger').Logger} logger
|
|
58
35
|
*/
|
|
59
|
-
export const makePsmCommand =
|
|
36
|
+
export const makePsmCommand = logger => {
|
|
60
37
|
const psm = new Command('psm').description('PSM commands').usage(
|
|
61
38
|
`
|
|
62
39
|
WALLET=my-wallet
|
|
63
40
|
export AGORIC_NET=ollinet
|
|
64
|
-
|
|
41
|
+
|
|
65
42
|
# provision wallet if necessary
|
|
66
43
|
agd keys add $WALLET
|
|
67
44
|
# provision with faucet, e.g.
|
|
@@ -74,7 +51,7 @@ export const makePsmCommand = async logger => {
|
|
|
74
51
|
# prepare an offer to send
|
|
75
52
|
# (offerId is optional but best to specify as each must be higher than the last and the default value is a huge number)
|
|
76
53
|
agops psm swap --wantMinted 6 --feePct 0.01 --offerId 12 > offer-12.json
|
|
77
|
-
|
|
54
|
+
|
|
78
55
|
# watch for results in one terminal
|
|
79
56
|
agoric wallet watch --from $WALLET
|
|
80
57
|
|
|
@@ -84,28 +61,45 @@ export const makePsmCommand = async logger => {
|
|
|
84
61
|
`,
|
|
85
62
|
);
|
|
86
63
|
|
|
87
|
-
const
|
|
64
|
+
const rpcTools = async () => {
|
|
65
|
+
const utils = await makeRpcUtils({ fetch });
|
|
88
66
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
67
|
+
const lookupPsmInstance = ([minted, anchor]) => {
|
|
68
|
+
const name = `psm-${minted}-${anchor}`;
|
|
69
|
+
const instance = utils.agoricNames.instance[name];
|
|
70
|
+
if (!instance) {
|
|
71
|
+
logger.debug('known instances:', utils.agoricNames.instance);
|
|
72
|
+
throw Error(`Unknown instance ${name}`);
|
|
73
|
+
}
|
|
74
|
+
return instance;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
*
|
|
79
|
+
* @param {[Minted: string, Anchor: string]} pair
|
|
80
|
+
*/
|
|
81
|
+
const getGovernanceState = async ([Minted, Anchor]) => {
|
|
82
|
+
const govContent = await utils.vstorage.readLatest(
|
|
83
|
+
`published.psm.${Minted}.${Anchor}.governance`,
|
|
84
|
+
);
|
|
85
|
+
assert(govContent, 'no gov content');
|
|
86
|
+
const { current: governance } = last(
|
|
87
|
+
storageHelper.unserializeTxt(govContent, utils.fromBoard),
|
|
88
|
+
);
|
|
89
|
+
const { [`psm.${Minted}.${Anchor}`]: instance } =
|
|
90
|
+
utils.agoricNames.instance;
|
|
98
91
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
92
|
+
return { instance, governance };
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
return { ...utils, lookupPsmInstance, getGovernanceState };
|
|
103
96
|
};
|
|
104
97
|
|
|
105
98
|
psm
|
|
106
99
|
.command('list')
|
|
107
100
|
.description('list all PSMs in network')
|
|
108
101
|
.action(async function () {
|
|
102
|
+
const { vstorage } = await rpcTools();
|
|
109
103
|
const mints = await vstorage.keys('published.psm');
|
|
110
104
|
for (const minted of mints) {
|
|
111
105
|
const anchors = await vstorage.keys(`published.psm.${minted}`);
|
|
@@ -125,8 +119,9 @@ export const makePsmCommand = async logger => {
|
|
|
125
119
|
s => s.split('.'),
|
|
126
120
|
['IST', 'AUSD'],
|
|
127
121
|
)
|
|
128
|
-
.action(async function () {
|
|
129
|
-
const { pair } =
|
|
122
|
+
.action(async function (opts) {
|
|
123
|
+
const { pair } = opts;
|
|
124
|
+
const { getGovernanceState } = await rpcTools();
|
|
130
125
|
const { governance } = await getGovernanceState(pair);
|
|
131
126
|
console.log('psm governance params', Object.keys(governance));
|
|
132
127
|
console.log('MintLimit', governance.MintLimit.value);
|
|
@@ -154,83 +149,29 @@ export const makePsmCommand = async logger => {
|
|
|
154
149
|
)
|
|
155
150
|
// wantMinted and giveMinted options conflict.
|
|
156
151
|
// TODO use .conflicts() after https://github.com/Agoric/agoric-sdk/issues/6181
|
|
157
|
-
.option('--wantMinted
|
|
158
|
-
.option('--giveMinted
|
|
152
|
+
.option('--wantMinted <DOLLARS>', 'amount of anchor tokens to give', Number)
|
|
153
|
+
.option('--giveMinted <DOLLARS>', 'amount of minted tokens to give', Number)
|
|
159
154
|
.option('--feePct [%]', 'Gas fee percentage', Number)
|
|
160
|
-
.option('--offerId
|
|
161
|
-
.action(async function (
|
|
162
|
-
|
|
155
|
+
.option('--offerId <string>', 'Offer id', String, `swap-${Date.now()}`)
|
|
156
|
+
.action(async function (
|
|
157
|
+
/** @type {Parameters<typeof Offers.psm.swap>[2]} */ opts,
|
|
158
|
+
) {
|
|
163
159
|
console.warn('running with options', opts);
|
|
160
|
+
const { agoricNames, lookupPsmInstance } = await rpcTools();
|
|
164
161
|
const instance = await lookupPsmInstance(opts.pair);
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
outputAction(spendAction);
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
psm
|
|
171
|
-
.command('committee')
|
|
172
|
-
.description('join the economic committee')
|
|
173
|
-
.option('--offerId [number]', 'Offer id', Number, Date.now())
|
|
174
|
-
.action(async function () {
|
|
175
|
-
const opts = this.opts();
|
|
176
|
-
|
|
177
|
-
const { economicCommittee } = agoricNames.instance;
|
|
178
|
-
assert(economicCommittee, 'missing economicCommittee');
|
|
179
|
-
|
|
180
|
-
/** @type {import('../lib/psm.js').OfferSpec} */
|
|
181
|
-
const offer = {
|
|
182
|
-
id: Number(opts.offerId),
|
|
183
|
-
invitationSpec: {
|
|
184
|
-
source: 'purse',
|
|
185
|
-
// @ts-expect-error xxx RpcRemote
|
|
186
|
-
instance: economicCommittee,
|
|
187
|
-
description: 'Voter0', // XXX it may not always be
|
|
188
|
-
},
|
|
189
|
-
proposal: {},
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
outputAction({
|
|
193
|
-
method: 'executeOffer',
|
|
194
|
-
offer,
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
console.warn('Now execute the prepared offer');
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
psm
|
|
201
|
-
.command('charter')
|
|
202
|
-
.description('prepare an offer to accept the charter invitation')
|
|
203
|
-
.option('--offerId [number]', 'Offer id', Number, Date.now())
|
|
204
|
-
.action(async function () {
|
|
205
|
-
const opts = this.opts();
|
|
206
|
-
|
|
207
|
-
const { psmCharter } = agoricNames.instance;
|
|
208
|
-
assert(psmCharter, 'missing psmCharter');
|
|
209
|
-
|
|
210
|
-
/** @type {import('../lib/psm.js').OfferSpec} */
|
|
211
|
-
const offer = {
|
|
212
|
-
id: Number(opts.offerId),
|
|
213
|
-
invitationSpec: {
|
|
214
|
-
source: 'purse',
|
|
215
|
-
// @ts-expect-error xxx RpcRemote
|
|
216
|
-
instance: psmCharter,
|
|
217
|
-
description: 'PSM charter member invitation',
|
|
218
|
-
},
|
|
219
|
-
proposal: {},
|
|
220
|
-
};
|
|
221
|
-
|
|
222
|
-
outputAction({
|
|
223
|
-
method: 'executeOffer',
|
|
224
|
-
offer,
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
console.warn('Now execute the prepared offer');
|
|
162
|
+
const offer = Offers.psm.swap(instance, agoricNames.brand, opts);
|
|
163
|
+
outputExecuteOfferAction(offer);
|
|
228
164
|
});
|
|
229
165
|
|
|
230
166
|
psm
|
|
231
167
|
.command('proposePauseOffers')
|
|
232
168
|
.description('propose a vote')
|
|
233
|
-
.option(
|
|
169
|
+
.option(
|
|
170
|
+
'--offerId <string>',
|
|
171
|
+
'Offer id',
|
|
172
|
+
String,
|
|
173
|
+
`proposePauseOffers-${Date.now()}`,
|
|
174
|
+
)
|
|
234
175
|
.requiredOption(
|
|
235
176
|
'--pair [Minted.Anchor]',
|
|
236
177
|
'token pair (Minted.Anchor)',
|
|
@@ -238,33 +179,31 @@ export const makePsmCommand = async logger => {
|
|
|
238
179
|
['IST', 'AUSD'],
|
|
239
180
|
)
|
|
240
181
|
.requiredOption(
|
|
241
|
-
'--
|
|
182
|
+
'--charterAcceptOfferId <string>',
|
|
242
183
|
'offer that had continuing invitation result',
|
|
243
|
-
Number,
|
|
244
184
|
)
|
|
245
185
|
.requiredOption(
|
|
246
|
-
'--substring
|
|
186
|
+
'--substring <string>',
|
|
247
187
|
'an offer string to pause (can be repeated)',
|
|
248
188
|
collectValues,
|
|
249
189
|
[],
|
|
250
190
|
)
|
|
251
191
|
.option(
|
|
252
|
-
'--deadline
|
|
192
|
+
'--deadline <minutes>',
|
|
253
193
|
'minutes from now to close the vote',
|
|
254
194
|
Number,
|
|
255
195
|
1,
|
|
256
196
|
)
|
|
257
|
-
.action(async function () {
|
|
258
|
-
const
|
|
259
|
-
|
|
197
|
+
.action(async function (opts) {
|
|
198
|
+
const { lookupPsmInstance } = await rpcTools();
|
|
260
199
|
const psmInstance = lookupPsmInstance(opts.pair);
|
|
261
200
|
|
|
262
|
-
/** @type {import('
|
|
201
|
+
/** @type {import('@agoric/smart-wallet/src/offers.js').OfferSpec} */
|
|
263
202
|
const offer = {
|
|
264
|
-
id:
|
|
203
|
+
id: opts.offerId,
|
|
265
204
|
invitationSpec: {
|
|
266
205
|
source: 'continuing',
|
|
267
|
-
previousOffer: opts.
|
|
206
|
+
previousOffer: opts.charterAcceptOfferId,
|
|
268
207
|
invitationMakerName: 'VoteOnPauseOffers',
|
|
269
208
|
// ( instance, strings list, timer deadline seconds )
|
|
270
209
|
invitationArgs: harden([
|
|
@@ -276,10 +215,7 @@ export const makePsmCommand = async logger => {
|
|
|
276
215
|
proposal: {},
|
|
277
216
|
};
|
|
278
217
|
|
|
279
|
-
|
|
280
|
-
method: 'executeOffer',
|
|
281
|
-
offer,
|
|
282
|
-
});
|
|
218
|
+
outputExecuteOfferAction(offer);
|
|
283
219
|
|
|
284
220
|
console.warn('Now execute the prepared offer');
|
|
285
221
|
});
|
|
@@ -288,10 +224,10 @@ export const makePsmCommand = async logger => {
|
|
|
288
224
|
.command('proposeChangeMintLimit')
|
|
289
225
|
.description('propose to change the MintLimit parameter')
|
|
290
226
|
.option(
|
|
291
|
-
'--offerId
|
|
227
|
+
'--offerId <string>',
|
|
292
228
|
'id of this offer (optional)',
|
|
293
|
-
|
|
294
|
-
Date.now()
|
|
229
|
+
String,
|
|
230
|
+
`proposeChangeMintLimit-${Date.now()}`,
|
|
295
231
|
)
|
|
296
232
|
.requiredOption(
|
|
297
233
|
'--pair [Minted.Anchor]',
|
|
@@ -300,20 +236,18 @@ export const makePsmCommand = async logger => {
|
|
|
300
236
|
['IST', 'AUSD'],
|
|
301
237
|
)
|
|
302
238
|
.requiredOption(
|
|
303
|
-
'--previousOfferId
|
|
239
|
+
'--previousOfferId <string>',
|
|
304
240
|
'offer using psm charter invitation',
|
|
305
|
-
Number,
|
|
306
241
|
)
|
|
307
|
-
.requiredOption('--limit
|
|
242
|
+
.requiredOption('--limit <number>', 'new mint limit (in IST)', Number)
|
|
308
243
|
.option(
|
|
309
|
-
'--deadline
|
|
244
|
+
'--deadline <minutes>',
|
|
310
245
|
'minutes from now to close the vote',
|
|
311
246
|
Number,
|
|
312
247
|
1,
|
|
313
248
|
)
|
|
314
|
-
.action(async function () {
|
|
315
|
-
const
|
|
316
|
-
|
|
249
|
+
.action(async function (opts) {
|
|
250
|
+
const { agoricNames, lookupPsmInstance } = await rpcTools();
|
|
317
251
|
const psmInstance = lookupPsmInstance(opts.pair);
|
|
318
252
|
|
|
319
253
|
const istBrand = agoricNames.brand.IST;
|
|
@@ -321,9 +255,9 @@ export const makePsmCommand = async logger => {
|
|
|
321
255
|
brand: istBrand,
|
|
322
256
|
value: BigInt(opts.limit * 1_000_000),
|
|
323
257
|
});
|
|
324
|
-
/** @type {import('
|
|
258
|
+
/** @type {import('@agoric/smart-wallet/src/offers.js').OfferSpec} */
|
|
325
259
|
const offer = {
|
|
326
|
-
id:
|
|
260
|
+
id: opts.offerId,
|
|
327
261
|
invitationSpec: {
|
|
328
262
|
source: 'continuing',
|
|
329
263
|
previousOffer: opts.previousOfferId,
|
|
@@ -337,76 +271,7 @@ export const makePsmCommand = async logger => {
|
|
|
337
271
|
},
|
|
338
272
|
};
|
|
339
273
|
|
|
340
|
-
|
|
341
|
-
method: 'executeOffer',
|
|
342
|
-
offer,
|
|
343
|
-
});
|
|
344
|
-
|
|
345
|
-
console.warn('Now execute the prepared offer');
|
|
346
|
-
});
|
|
347
|
-
|
|
348
|
-
psm
|
|
349
|
-
.command('vote')
|
|
350
|
-
.description('vote on a question (hard-coded for now))')
|
|
351
|
-
.option('--offerId [number]', 'Offer id', Number, Date.now())
|
|
352
|
-
.requiredOption(
|
|
353
|
-
'--econCommAcceptOfferId [number]',
|
|
354
|
-
'offer that had continuing invitation result',
|
|
355
|
-
Number,
|
|
356
|
-
)
|
|
357
|
-
.requiredOption(
|
|
358
|
-
'--pair [Minted.Anchor]',
|
|
359
|
-
'token pair (Minted.Anchor)',
|
|
360
|
-
s => s.split('.'),
|
|
361
|
-
['IST', 'AUSD'],
|
|
362
|
-
)
|
|
363
|
-
.requiredOption(
|
|
364
|
-
'--forPosition [number]',
|
|
365
|
-
'index of one position to vote for (within the question description.positions); ',
|
|
366
|
-
Number,
|
|
367
|
-
)
|
|
368
|
-
.action(async function () {
|
|
369
|
-
const opts = this.opts();
|
|
370
|
-
|
|
371
|
-
const questionHandleCapDataStr = await vstorage.readLatest(
|
|
372
|
-
'published.committees.Economic_Committee.latestQuestion',
|
|
373
|
-
);
|
|
374
|
-
const questionDescriptions = storageHelper.unserializeTxt(
|
|
375
|
-
questionHandleCapDataStr,
|
|
376
|
-
fromBoard,
|
|
377
|
-
);
|
|
378
|
-
|
|
379
|
-
assert(questionDescriptions, 'missing questionDescriptions');
|
|
380
|
-
assert(
|
|
381
|
-
questionDescriptions.length === 1,
|
|
382
|
-
'multiple questions not supported',
|
|
383
|
-
);
|
|
384
|
-
|
|
385
|
-
const questionDesc = questionDescriptions[0];
|
|
386
|
-
// TODO support multiple position arguments
|
|
387
|
-
const chosenPositions = [questionDesc.positions[opts.forPosition]];
|
|
388
|
-
assert(chosenPositions, `undefined position index ${opts.forPosition}`);
|
|
389
|
-
|
|
390
|
-
/** @type {import('../lib/psm.js').OfferSpec} */
|
|
391
|
-
const offer = {
|
|
392
|
-
id: Number(opts.offerId),
|
|
393
|
-
invitationSpec: {
|
|
394
|
-
source: 'continuing',
|
|
395
|
-
previousOffer: opts.previousOfferId,
|
|
396
|
-
invitationMakerName: 'makeVoteInvitation',
|
|
397
|
-
// (positionList, questionHandle)
|
|
398
|
-
invitationArgs: harden([
|
|
399
|
-
chosenPositions,
|
|
400
|
-
questionDesc.questionHandle,
|
|
401
|
-
]),
|
|
402
|
-
},
|
|
403
|
-
proposal: {},
|
|
404
|
-
};
|
|
405
|
-
|
|
406
|
-
outputAction({
|
|
407
|
-
method: 'executeOffer',
|
|
408
|
-
offer,
|
|
409
|
-
});
|
|
274
|
+
outputExecuteOfferAction(offer);
|
|
410
275
|
|
|
411
276
|
console.warn('Now execute the prepared offer');
|
|
412
277
|
});
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/* eslint-disable @jessie.js/no-nested-await */
|
|
2
|
+
// @ts-check
|
|
3
|
+
/* eslint-disable func-names */
|
|
4
|
+
/* global fetch, process */
|
|
5
|
+
import { Offers } from '@agoric/inter-protocol/src/clientSupport.js';
|
|
6
|
+
import { Command } from 'commander';
|
|
7
|
+
import { makeRpcUtils } from '../lib/rpc.js';
|
|
8
|
+
import { outputActionAndHint } from '../lib/wallet.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @param {import('anylogger').Logger} _logger
|
|
12
|
+
* @param {*} io
|
|
13
|
+
*/
|
|
14
|
+
export const makeReserveCommand = (_logger, io = {}) => {
|
|
15
|
+
const { stdout = process.stdout, stderr = process.stderr, now } = io;
|
|
16
|
+
const reserve = new Command('reserve').description('Asset Reserve commands');
|
|
17
|
+
|
|
18
|
+
reserve
|
|
19
|
+
.command('add')
|
|
20
|
+
.description('add collateral to the reserve')
|
|
21
|
+
.requiredOption('--give <number>', 'Collateral to give', Number)
|
|
22
|
+
.option('--collateral-brand <string>', 'Collateral brand key', 'ATOM')
|
|
23
|
+
.option('--offer-id <string>', 'Offer id', String, `addCollateral-${now()}`)
|
|
24
|
+
.action(
|
|
25
|
+
/**
|
|
26
|
+
* @param {{
|
|
27
|
+
* give: number,
|
|
28
|
+
* collateralBrand: string,
|
|
29
|
+
* offerId: string,
|
|
30
|
+
* }} opts
|
|
31
|
+
*/
|
|
32
|
+
async ({ collateralBrand, ...opts }) => {
|
|
33
|
+
const { agoricNames } = await makeRpcUtils({ fetch });
|
|
34
|
+
|
|
35
|
+
const offer = Offers.reserve.AddCollateral(agoricNames.brand, {
|
|
36
|
+
collateralBrandKey: collateralBrand,
|
|
37
|
+
...opts,
|
|
38
|
+
});
|
|
39
|
+
outputActionAndHint(
|
|
40
|
+
{ method: 'executeOffer', offer },
|
|
41
|
+
{ stdout, stderr },
|
|
42
|
+
);
|
|
43
|
+
},
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
reserve
|
|
47
|
+
.command('proposeBurn')
|
|
48
|
+
.description('propose a call to burnFeesToReduceShortfall')
|
|
49
|
+
.option(
|
|
50
|
+
'--offerId <string>',
|
|
51
|
+
'Offer id',
|
|
52
|
+
String,
|
|
53
|
+
`proposePauseOffers-${Date.now()}`,
|
|
54
|
+
)
|
|
55
|
+
.requiredOption(
|
|
56
|
+
'--charterAcceptOfferId <string>',
|
|
57
|
+
'offer that had continuing invitation result',
|
|
58
|
+
)
|
|
59
|
+
.requiredOption('--value [integer]', 'value of µIST to burn', BigInt)
|
|
60
|
+
.option(
|
|
61
|
+
'--deadline <minutes>',
|
|
62
|
+
'minutes from now to close the vote',
|
|
63
|
+
Number,
|
|
64
|
+
1,
|
|
65
|
+
)
|
|
66
|
+
.action(async function (opts) {
|
|
67
|
+
const { agoricNames } = await makeRpcUtils({ fetch });
|
|
68
|
+
|
|
69
|
+
const reserveInstance = agoricNames.instance.reserve;
|
|
70
|
+
assert(reserveInstance, 'missing reserve in names');
|
|
71
|
+
|
|
72
|
+
const feesToBurn = { brand: agoricNames.brand.IST, value: opts.value };
|
|
73
|
+
|
|
74
|
+
/** @type {import('@agoric/smart-wallet/src/offers.js').OfferSpec} */
|
|
75
|
+
const offer = {
|
|
76
|
+
id: opts.offerId,
|
|
77
|
+
invitationSpec: {
|
|
78
|
+
source: 'continuing',
|
|
79
|
+
previousOffer: opts.charterAcceptOfferId,
|
|
80
|
+
invitationMakerName: 'VoteOnApiCall',
|
|
81
|
+
invitationArgs: harden([
|
|
82
|
+
reserveInstance,
|
|
83
|
+
'burnFeesToReduceShortfall',
|
|
84
|
+
[feesToBurn],
|
|
85
|
+
BigInt(opts.deadline * 60 + Math.round(Date.now() / 1000)),
|
|
86
|
+
]),
|
|
87
|
+
},
|
|
88
|
+
proposal: {},
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
outputActionAndHint(
|
|
92
|
+
{ method: 'executeOffer', offer },
|
|
93
|
+
{ stdout, stderr },
|
|
94
|
+
);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
return reserve;
|
|
98
|
+
};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
/* global process */
|
|
3
|
+
import { Fail } from '@agoric/assert';
|
|
4
|
+
import { CommanderError } from 'commander';
|
|
5
|
+
import { normalizeAddressWithOptions } from '../lib/chain.js';
|
|
6
|
+
import { bigintReplacer } from '../lib/format.js';
|
|
7
|
+
import { getNetworkConfig } from '../lib/rpc.js';
|
|
8
|
+
import { makeWalletUtils, sendAction } from '../lib/wallet.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Make commands for testing.
|
|
12
|
+
*
|
|
13
|
+
* @param {{
|
|
14
|
+
* env: Partial<Record<string, string>>,
|
|
15
|
+
* stdout: Pick<import('stream').Writable,'write'>,
|
|
16
|
+
* stderr: Pick<import('stream').Writable,'write'>,
|
|
17
|
+
* now: () => number,
|
|
18
|
+
* createCommand: // Note: includes access to process.stdout, .stderr, .exit
|
|
19
|
+
* typeof import('commander').createCommand,
|
|
20
|
+
* execFileSync: typeof import('child_process').execFileSync,
|
|
21
|
+
* setTimeout: typeof setTimeout,
|
|
22
|
+
* }} process
|
|
23
|
+
* @param {{ fetch: typeof window.fetch }} net
|
|
24
|
+
*/
|
|
25
|
+
export const makeTestCommand = (
|
|
26
|
+
{ env, stdout, now, setTimeout, execFileSync, createCommand },
|
|
27
|
+
{ fetch },
|
|
28
|
+
) => {
|
|
29
|
+
/** @param {number} ms */
|
|
30
|
+
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
|
|
31
|
+
const show = (info, indent = false) =>
|
|
32
|
+
stdout.write(
|
|
33
|
+
`${JSON.stringify(info, bigintReplacer, indent ? 2 : undefined)}\n`,
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
const tryMakeUtils = async () => {
|
|
37
|
+
await null;
|
|
38
|
+
try {
|
|
39
|
+
// XXX pass fetch to getNetworkConfig() explicitly
|
|
40
|
+
// await null above makes this await safe
|
|
41
|
+
// eslint-disable-next-line @jessie.js/no-nested-await
|
|
42
|
+
const networkConfig = await getNetworkConfig(env);
|
|
43
|
+
return makeWalletUtils({ fetch, execFileSync, delay }, networkConfig);
|
|
44
|
+
} catch (err) {
|
|
45
|
+
throw new CommanderError(1, 'RPC_FAIL', err.message);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const testCmd = createCommand('test').description('test operations');
|
|
50
|
+
|
|
51
|
+
testCmd
|
|
52
|
+
.command('upgrade-contract')
|
|
53
|
+
.description('make simple offer to upgrade-contract')
|
|
54
|
+
.option('--home <dir>', 'agd CosmosSDK application home directory')
|
|
55
|
+
.option(
|
|
56
|
+
'--keyring-backend <os|file|test>',
|
|
57
|
+
`keyring's backend (os|file|test) (default "${
|
|
58
|
+
env.AGORIC_KEYRING_BACKEND || 'os'
|
|
59
|
+
}")`,
|
|
60
|
+
env.AGORIC_KEYRING_BACKEND,
|
|
61
|
+
)
|
|
62
|
+
.option('--offer-id <string>', 'Offer id', String, `my-${now()}`)
|
|
63
|
+
.requiredOption(
|
|
64
|
+
'--from <address>',
|
|
65
|
+
'wallet address literal or name',
|
|
66
|
+
literalOrName =>
|
|
67
|
+
normalizeAddressWithOptions(literalOrName, testCmd.opts(), {
|
|
68
|
+
execFileSync,
|
|
69
|
+
}),
|
|
70
|
+
)
|
|
71
|
+
.action(async opts => {
|
|
72
|
+
const { agoricNames, networkConfig, pollOffer } = await tryMakeUtils();
|
|
73
|
+
const { from } = opts;
|
|
74
|
+
const { home, keyringBackend: backend } = testCmd.opts();
|
|
75
|
+
|
|
76
|
+
const io = { ...networkConfig, execFileSync, delay, stdout };
|
|
77
|
+
/** @type {import('@agoric/smart-wallet/src/offers.js').OfferSpec} */
|
|
78
|
+
const offer = {
|
|
79
|
+
id: opts.offerId,
|
|
80
|
+
invitationSpec: {
|
|
81
|
+
source: 'contract',
|
|
82
|
+
instance: agoricNames.instance.myInstance || Fail`no myInstance`,
|
|
83
|
+
publicInvitationMaker: 'makeInvitation',
|
|
84
|
+
},
|
|
85
|
+
proposal: {
|
|
86
|
+
want: { Tokens: { brand: agoricNames.brand.GoodStuff, value: 32n } },
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
const result = await sendAction(
|
|
90
|
+
{
|
|
91
|
+
method: 'executeOffer',
|
|
92
|
+
offer,
|
|
93
|
+
},
|
|
94
|
+
{ keyring: { home, backend }, from, verbose: false, ...io },
|
|
95
|
+
);
|
|
96
|
+
if (result?.code !== 0) {
|
|
97
|
+
throw result;
|
|
98
|
+
}
|
|
99
|
+
show({ height: result?.height, txhash: result?.txhash });
|
|
100
|
+
const found = await pollOffer(from, offer.id, result.height, true);
|
|
101
|
+
show(found, true);
|
|
102
|
+
const numWantsSatisfied = found.numWantsSatisfied || 0;
|
|
103
|
+
if (numWantsSatisfied < 1) {
|
|
104
|
+
process.exit(2);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
return testCmd;
|
|
109
|
+
};
|