agoric 0.21.2-other-dev-8f8782b.0 → 0.21.2-other-dev-3eb1a1d.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 +53 -38
- package/src/anylogger-agoric.js +31 -16
- package/src/bin-agops.js +8 -10
- package/src/chain-config.js +33 -14
- package/src/commands/auction.js +17 -18
- package/src/commands/{ec.js → gov.js} +211 -59
- package/src/commands/inter.js +45 -62
- package/src/commands/oracle.js +98 -61
- package/src/commands/perf.js +6 -6
- package/src/commands/psm.js +19 -20
- package/src/commands/reserve.js +8 -6
- package/src/commands/test-upgrade.js +16 -8
- package/src/commands/vaults.js +25 -18
- package/src/commands/wallet.js +105 -35
- package/src/cosmos.js +3 -3
- package/src/deploy.js +3 -4
- package/src/entrypoint.js +1 -3
- package/src/follow.js +6 -3
- package/src/helpers.js +9 -5
- package/src/init.js +2 -9
- package/src/install.js +17 -16
- package/src/lib/bundles.js +102 -0
- package/src/lib/chain.js +63 -12
- package/src/lib/format.js +28 -34
- package/src/lib/network-config.js +41 -0
- package/src/lib/wallet.js +43 -143
- package/src/main-publish.js +2 -3
- package/src/main.js +91 -89
- package/src/open.js +8 -10
- package/src/publish.js +4 -9
- package/src/scripts.js +13 -4
- package/src/sdk-package-names.js +13 -7
- package/src/set-defaults.js +2 -1
- package/src/start.js +59 -67
- package/tools/getting-started.js +254 -0
- package/tools/resm-plugin/deploy.js +18 -0
- package/tools/resm-plugin/package.json +12 -0
- package/tools/resm-plugin/src/output.js +1 -0
- package/tools/resm-plugin/src/plugin.js +17 -0
- package/CHANGELOG.md +0 -1069
- package/src/lib/rpc.js +0 -272
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
/* eslint-disable @jessie.js/no-nested-await */
|
|
2
1
|
// @ts-check
|
|
3
2
|
/* eslint-disable func-names */
|
|
4
|
-
/*
|
|
3
|
+
/* eslint-env node */
|
|
4
|
+
import { makeVstorageKit } from '@agoric/client-utils';
|
|
5
5
|
import { execFileSync as execFileSyncAmbient } from 'child_process';
|
|
6
6
|
import { Command, CommanderError } from 'commander';
|
|
7
7
|
import { normalizeAddressWithOptions, pollBlocks } from '../lib/chain.js';
|
|
8
|
-
import { getNetworkConfig
|
|
8
|
+
import { getNetworkConfig } from '../lib/network-config.js';
|
|
9
9
|
import {
|
|
10
10
|
findContinuingIds,
|
|
11
11
|
getCurrent,
|
|
@@ -14,7 +14,19 @@ import {
|
|
|
14
14
|
sendAction,
|
|
15
15
|
} from '../lib/wallet.js';
|
|
16
16
|
|
|
17
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* @import {OfferSpec} from '@agoric/smart-wallet/src/offers.js'
|
|
19
|
+
* @import {QuestionDetails} from '@agoric/governance/src/types.js'
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
const collectValues = (val, memo) => {
|
|
23
|
+
memo.push(val);
|
|
24
|
+
return memo;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const defaultKeyring = process.env.AGORIC_KEYRING_BACKEND || 'test';
|
|
28
|
+
|
|
29
|
+
const networkConfig = await getNetworkConfig({ env: process.env, fetch });
|
|
18
30
|
|
|
19
31
|
/**
|
|
20
32
|
* @param {import('anylogger').Logger} _logger
|
|
@@ -27,23 +39,33 @@ import {
|
|
|
27
39
|
* delay?: (ms: number) => Promise<void>,
|
|
28
40
|
* }} [io]
|
|
29
41
|
*/
|
|
30
|
-
export const
|
|
42
|
+
export const makeGovCommand = (_logger, io = {}) => {
|
|
31
43
|
const {
|
|
32
44
|
// Allow caller to provide access explicitly, but
|
|
33
45
|
// default to conventional ambient IO facilities.
|
|
34
|
-
env = process.env,
|
|
35
46
|
stdout = process.stdout,
|
|
36
47
|
stderr = process.stderr,
|
|
37
|
-
fetch =
|
|
48
|
+
fetch = global.fetch,
|
|
38
49
|
execFileSync = execFileSyncAmbient,
|
|
39
50
|
delay = ms => new Promise(resolve => setTimeout(resolve, ms)),
|
|
40
51
|
} = io;
|
|
41
52
|
|
|
42
|
-
const
|
|
53
|
+
const cmd = new Command('gov').description('Electoral governance commands');
|
|
54
|
+
// backwards compatibility with less general "ec" command. To make this work
|
|
55
|
+
// the new CLI options default to the values used for Economic Committee
|
|
56
|
+
cmd.alias('ec');
|
|
57
|
+
cmd.option(
|
|
58
|
+
'--keyring-backend <os|file|test>',
|
|
59
|
+
`keyring's backend (os|file|test) (default "${defaultKeyring}")`,
|
|
60
|
+
defaultKeyring,
|
|
61
|
+
);
|
|
43
62
|
|
|
44
63
|
/** @param {string} literalOrName */
|
|
45
64
|
const normalizeAddress = literalOrName =>
|
|
46
|
-
normalizeAddressWithOptions(literalOrName, {
|
|
65
|
+
normalizeAddressWithOptions(literalOrName, {
|
|
66
|
+
// FIXME does not observe keyring-backend option, which isn't available during arg parsing
|
|
67
|
+
keyringBackend: defaultKeyring,
|
|
68
|
+
});
|
|
47
69
|
|
|
48
70
|
/** @type {(info: unknown, indent?: unknown) => boolean } */
|
|
49
71
|
const show = (info, indent) =>
|
|
@@ -53,6 +75,8 @@ export const makeEconomicCommiteeCommand = (_logger, io = {}) => {
|
|
|
53
75
|
const done = found.filter(it => it.instanceName === instanceName);
|
|
54
76
|
if (done.length > 0) {
|
|
55
77
|
console.warn(`invitation to ${instanceName} already accepted`, done);
|
|
78
|
+
// CommanderError is a class constructor, and so
|
|
79
|
+
// must be invoked with `new`.
|
|
56
80
|
throw new CommanderError(1, 'EALREADY', `already accepted`);
|
|
57
81
|
}
|
|
58
82
|
};
|
|
@@ -62,20 +86,25 @@ export const makeEconomicCommiteeCommand = (_logger, io = {}) => {
|
|
|
62
86
|
* given a sendFrom address; else print it.
|
|
63
87
|
*
|
|
64
88
|
* @param {{
|
|
65
|
-
* toOffer: (agoricNames: *, current: import('@agoric/smart-wallet/src/smartWallet').CurrentWalletRecord | undefined) => OfferSpec,
|
|
89
|
+
* toOffer: (agoricNames: *, current: import('@agoric/smart-wallet/src/smartWallet.js').CurrentWalletRecord | undefined) => OfferSpec,
|
|
66
90
|
* sendFrom?: string | undefined,
|
|
91
|
+
* keyringBackend: string,
|
|
67
92
|
* instanceName?: string,
|
|
68
93
|
* }} detail
|
|
69
|
-
* @param {Awaited<ReturnType<
|
|
94
|
+
* @param {Awaited<ReturnType<makeVstorageKit>>} [optUtils]
|
|
70
95
|
*/
|
|
71
|
-
const processOffer = async function (
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
96
|
+
const processOffer = async function (
|
|
97
|
+
{ toOffer, sendFrom, keyringBackend },
|
|
98
|
+
optUtils,
|
|
99
|
+
) {
|
|
100
|
+
const utils = await (optUtils || makeVstorageKit({ fetch }, networkConfig));
|
|
101
|
+
const { agoricNames, readPublished } = utils;
|
|
102
|
+
|
|
103
|
+
assert(keyringBackend, 'missing keyring-backend option');
|
|
75
104
|
|
|
76
105
|
let current;
|
|
77
106
|
if (sendFrom) {
|
|
78
|
-
current = await getCurrent(sendFrom, {
|
|
107
|
+
current = await getCurrent(sendFrom, { readPublished });
|
|
79
108
|
}
|
|
80
109
|
|
|
81
110
|
const offer = toOffer(agoricNames, current);
|
|
@@ -90,7 +119,7 @@ export const makeEconomicCommiteeCommand = (_logger, io = {}) => {
|
|
|
90
119
|
const result = await sendAction(
|
|
91
120
|
{ method: 'executeOffer', offer },
|
|
92
121
|
{
|
|
93
|
-
keyring: { backend:
|
|
122
|
+
keyring: { backend: keyringBackend },
|
|
94
123
|
from: sendFrom,
|
|
95
124
|
verbose: false,
|
|
96
125
|
...networkConfig,
|
|
@@ -105,9 +134,9 @@ export const makeEconomicCommiteeCommand = (_logger, io = {}) => {
|
|
|
105
134
|
show({ timestamp, height, offerId: offer.id, txhash });
|
|
106
135
|
const checkInWallet = async blockInfo => {
|
|
107
136
|
const [state, update] = await Promise.all([
|
|
108
|
-
getCurrent(sendFrom, {
|
|
109
|
-
getLastUpdate(sendFrom, {
|
|
110
|
-
|
|
137
|
+
getCurrent(sendFrom, { readPublished }),
|
|
138
|
+
getLastUpdate(sendFrom, { readPublished }),
|
|
139
|
+
readPublished(`wallet.${sendFrom}`),
|
|
111
140
|
]);
|
|
112
141
|
if (update.updated === 'offerStatus' && update.status.id === offer.id) {
|
|
113
142
|
return blockInfo;
|
|
@@ -127,29 +156,38 @@ export const makeEconomicCommiteeCommand = (_logger, io = {}) => {
|
|
|
127
156
|
show(blockInfo);
|
|
128
157
|
};
|
|
129
158
|
|
|
130
|
-
|
|
131
|
-
.
|
|
159
|
+
cmd
|
|
160
|
+
.command('committee')
|
|
161
|
+
.description('accept invitation to join a committee')
|
|
162
|
+
.requiredOption(
|
|
163
|
+
'--name <string>',
|
|
164
|
+
'Committee instance name',
|
|
165
|
+
String,
|
|
166
|
+
'economicCommittee',
|
|
167
|
+
)
|
|
132
168
|
.option('--voter <number>', 'Voter number', Number, 0)
|
|
133
169
|
.option(
|
|
134
170
|
'--offerId <string>',
|
|
135
171
|
'Offer id',
|
|
136
172
|
String,
|
|
137
|
-
`
|
|
173
|
+
`gov-committee-${Date.now()}`,
|
|
138
174
|
)
|
|
139
175
|
.option(
|
|
140
176
|
'--send-from <name-or-address>',
|
|
141
177
|
'Send from address',
|
|
142
178
|
normalizeAddress,
|
|
143
179
|
)
|
|
144
|
-
.action(async function (opts) {
|
|
180
|
+
.action(async function (opts, options) {
|
|
181
|
+
const { name: instanceName } = opts;
|
|
182
|
+
|
|
145
183
|
/** @type {Parameters<typeof processOffer>[0]['toOffer']} */
|
|
146
184
|
const toOffer = (agoricNames, current) => {
|
|
147
|
-
const instance = agoricNames.instance
|
|
148
|
-
assert(instance, `missing
|
|
185
|
+
const instance = agoricNames.instance[instanceName];
|
|
186
|
+
assert(instance, `missing ${instanceName}`);
|
|
149
187
|
|
|
150
188
|
if (current) {
|
|
151
189
|
const found = findContinuingIds(current, agoricNames);
|
|
152
|
-
abortIfSeen(
|
|
190
|
+
abortIfSeen(instanceName, found);
|
|
153
191
|
}
|
|
154
192
|
|
|
155
193
|
return {
|
|
@@ -165,28 +203,37 @@ export const makeEconomicCommiteeCommand = (_logger, io = {}) => {
|
|
|
165
203
|
|
|
166
204
|
await processOffer({
|
|
167
205
|
toOffer,
|
|
168
|
-
instanceName
|
|
169
|
-
|
|
206
|
+
instanceName,
|
|
207
|
+
sendFrom: opts.sendFrom,
|
|
208
|
+
keyringBackend: options.optsWithGlobals().keyringBackend,
|
|
170
209
|
});
|
|
171
210
|
});
|
|
172
211
|
|
|
173
|
-
|
|
212
|
+
cmd
|
|
213
|
+
.command('charter')
|
|
174
214
|
.description('accept the charter invitation')
|
|
175
|
-
.
|
|
215
|
+
.requiredOption(
|
|
216
|
+
'--name <string>',
|
|
217
|
+
'Charter instance name',
|
|
218
|
+
'economicCommitteeCharter',
|
|
219
|
+
)
|
|
220
|
+
.option('--offerId <string>', 'Offer id', String, `charter-${Date.now()}`)
|
|
176
221
|
.option(
|
|
177
222
|
'--send-from <name-or-address>',
|
|
178
223
|
'Send from address',
|
|
179
224
|
normalizeAddress,
|
|
180
225
|
)
|
|
181
|
-
.action(async function (opts) {
|
|
226
|
+
.action(async function (opts, options) {
|
|
227
|
+
const { name: instanceName } = opts;
|
|
228
|
+
|
|
182
229
|
/** @type {Parameters<typeof processOffer>[0]['toOffer']} */
|
|
183
230
|
const toOffer = (agoricNames, current) => {
|
|
184
|
-
const instance = agoricNames.instance
|
|
185
|
-
assert(instance, `missing
|
|
231
|
+
const instance = agoricNames.instance[instanceName];
|
|
232
|
+
assert(instance, `missing ${instanceName}`);
|
|
186
233
|
|
|
187
234
|
if (current) {
|
|
188
235
|
const found = findContinuingIds(current, agoricNames);
|
|
189
|
-
abortIfSeen(
|
|
236
|
+
abortIfSeen(instanceName, found);
|
|
190
237
|
}
|
|
191
238
|
|
|
192
239
|
return {
|
|
@@ -202,12 +249,14 @@ export const makeEconomicCommiteeCommand = (_logger, io = {}) => {
|
|
|
202
249
|
|
|
203
250
|
await processOffer({
|
|
204
251
|
toOffer,
|
|
205
|
-
instanceName
|
|
206
|
-
|
|
252
|
+
instanceName,
|
|
253
|
+
sendFrom: opts.sendFrom,
|
|
254
|
+
keyringBackend: options.optsWithGlobals().keyringBackend,
|
|
207
255
|
});
|
|
208
256
|
});
|
|
209
257
|
|
|
210
|
-
|
|
258
|
+
cmd
|
|
259
|
+
.command('find-continuing-id')
|
|
211
260
|
.description('print id of specified voting continuing invitation')
|
|
212
261
|
.requiredOption(
|
|
213
262
|
'--from <name-or-address>',
|
|
@@ -216,8 +265,11 @@ export const makeEconomicCommiteeCommand = (_logger, io = {}) => {
|
|
|
216
265
|
)
|
|
217
266
|
.requiredOption('--for <string>', 'description of the invitation')
|
|
218
267
|
.action(async opts => {
|
|
219
|
-
const { agoricNames,
|
|
220
|
-
|
|
268
|
+
const { agoricNames, readPublished } = await makeVstorageKit(
|
|
269
|
+
{ fetch },
|
|
270
|
+
networkConfig,
|
|
271
|
+
);
|
|
272
|
+
const current = await getCurrent(opts.from, { readPublished });
|
|
221
273
|
|
|
222
274
|
const known = findContinuingIds(current, agoricNames);
|
|
223
275
|
if (!known) {
|
|
@@ -233,7 +285,8 @@ export const makeEconomicCommiteeCommand = (_logger, io = {}) => {
|
|
|
233
285
|
console.log(match.offerId);
|
|
234
286
|
});
|
|
235
287
|
|
|
236
|
-
|
|
288
|
+
cmd
|
|
289
|
+
.command('find-continuing-ids')
|
|
237
290
|
.description('print records of voting continuing invitations')
|
|
238
291
|
.requiredOption(
|
|
239
292
|
'--from <name-or-address>',
|
|
@@ -241,16 +294,34 @@ export const makeEconomicCommiteeCommand = (_logger, io = {}) => {
|
|
|
241
294
|
normalizeAddress,
|
|
242
295
|
)
|
|
243
296
|
.action(async opts => {
|
|
244
|
-
const { agoricNames,
|
|
245
|
-
|
|
297
|
+
const { agoricNames, readPublished } = await makeVstorageKit(
|
|
298
|
+
{ fetch },
|
|
299
|
+
networkConfig,
|
|
300
|
+
);
|
|
301
|
+
const current = await getCurrent(opts.from, { readPublished });
|
|
246
302
|
|
|
247
303
|
const found = findContinuingIds(current, agoricNames);
|
|
248
|
-
|
|
304
|
+
for (const it of found) {
|
|
305
|
+
show({ ...it, address: opts.from });
|
|
306
|
+
}
|
|
249
307
|
});
|
|
250
308
|
|
|
251
|
-
|
|
252
|
-
.
|
|
253
|
-
.
|
|
309
|
+
cmd
|
|
310
|
+
.command('vote')
|
|
311
|
+
.description('vote on latest question')
|
|
312
|
+
.requiredOption(
|
|
313
|
+
'--instance <string>',
|
|
314
|
+
'Committee name under agoricNames.instances',
|
|
315
|
+
String,
|
|
316
|
+
'economicCommittee',
|
|
317
|
+
)
|
|
318
|
+
.requiredOption(
|
|
319
|
+
'--pathname <string>',
|
|
320
|
+
'Committee name under published.committees',
|
|
321
|
+
String,
|
|
322
|
+
'Economic_Committee',
|
|
323
|
+
)
|
|
324
|
+
.option('--offerId <number>', 'Offer id', String, `gov-vote-${Date.now()}`)
|
|
254
325
|
.requiredOption(
|
|
255
326
|
'--forPosition <number>',
|
|
256
327
|
'index of one position to vote for (within the question description.positions); ',
|
|
@@ -261,17 +332,17 @@ export const makeEconomicCommiteeCommand = (_logger, io = {}) => {
|
|
|
261
332
|
'Send from address',
|
|
262
333
|
normalizeAddress,
|
|
263
334
|
)
|
|
264
|
-
.action(async function (opts) {
|
|
265
|
-
const utils = await
|
|
266
|
-
const {
|
|
335
|
+
.action(async function (opts, options) {
|
|
336
|
+
const utils = await makeVstorageKit({ fetch }, networkConfig);
|
|
337
|
+
const { readPublished } = utils;
|
|
267
338
|
|
|
268
|
-
const
|
|
269
|
-
|
|
339
|
+
const questionDesc = await readPublished(
|
|
340
|
+
`committees.${opts.pathname}.latestQuestion`,
|
|
270
341
|
).catch(err => {
|
|
342
|
+
// CommanderError is a class constructor, and so
|
|
343
|
+
// must be invoked with `new`.
|
|
271
344
|
throw new CommanderError(1, 'VSTORAGE_FAILURE', err.message);
|
|
272
345
|
});
|
|
273
|
-
// XXX runtime shape-check
|
|
274
|
-
const questionDesc = /** @type {any} */ (info);
|
|
275
346
|
|
|
276
347
|
// TODO support multiple position arguments
|
|
277
348
|
const chosenPositions = [questionDesc.positions[opts.forPosition]];
|
|
@@ -280,11 +351,11 @@ export const makeEconomicCommiteeCommand = (_logger, io = {}) => {
|
|
|
280
351
|
/** @type {Parameters<typeof processOffer>[0]['toOffer']} */
|
|
281
352
|
const toOffer = (agoricNames, current) => {
|
|
282
353
|
const cont = current ? findContinuingIds(current, agoricNames) : [];
|
|
283
|
-
const votingRight = cont.find(
|
|
284
|
-
it => it.instance === agoricNames.instance.economicCommittee,
|
|
285
|
-
);
|
|
354
|
+
const votingRight = cont.find(it => it.instanceName === opts.instance);
|
|
286
355
|
if (!votingRight) {
|
|
287
356
|
console.debug('continuing ids', cont, 'for', current);
|
|
357
|
+
// CommanderError is a class constructor, and so
|
|
358
|
+
// must be invoked with `new`.
|
|
288
359
|
throw new CommanderError(
|
|
289
360
|
1,
|
|
290
361
|
'NO_INVITATION',
|
|
@@ -307,8 +378,89 @@ export const makeEconomicCommiteeCommand = (_logger, io = {}) => {
|
|
|
307
378
|
};
|
|
308
379
|
};
|
|
309
380
|
|
|
310
|
-
await processOffer(
|
|
381
|
+
await processOffer(
|
|
382
|
+
{
|
|
383
|
+
toOffer,
|
|
384
|
+
sendFrom: opts.sendFrom,
|
|
385
|
+
keyringBackend: options.optsWithGlobals().keyringBackend,
|
|
386
|
+
},
|
|
387
|
+
utils,
|
|
388
|
+
);
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
cmd
|
|
392
|
+
.command('proposePauseOffers')
|
|
393
|
+
.description('propose a vote to pause offers')
|
|
394
|
+
.option(
|
|
395
|
+
'--send-from <name-or-address>',
|
|
396
|
+
'Send from address',
|
|
397
|
+
normalizeAddress,
|
|
398
|
+
)
|
|
399
|
+
.option(
|
|
400
|
+
'--offerId <string>',
|
|
401
|
+
'Offer id',
|
|
402
|
+
String,
|
|
403
|
+
`proposePauseOffers-${Date.now()}`,
|
|
404
|
+
)
|
|
405
|
+
.requiredOption(
|
|
406
|
+
'--instance <string>',
|
|
407
|
+
'name of governed instance in agoricNames',
|
|
408
|
+
)
|
|
409
|
+
.requiredOption(
|
|
410
|
+
'--substring <string>',
|
|
411
|
+
'an offer string to pause (can be repeated)',
|
|
412
|
+
collectValues,
|
|
413
|
+
[],
|
|
414
|
+
)
|
|
415
|
+
.option(
|
|
416
|
+
'--deadline <minutes>',
|
|
417
|
+
'minutes from now to close the vote',
|
|
418
|
+
Number,
|
|
419
|
+
1,
|
|
420
|
+
)
|
|
421
|
+
.action(async function (opts, options) {
|
|
422
|
+
const { instance: instanceName } = opts;
|
|
423
|
+
|
|
424
|
+
/** @type {Parameters<typeof processOffer>[0]['toOffer']} */
|
|
425
|
+
const toOffer = (agoricNames, current) => {
|
|
426
|
+
const instance = agoricNames.instance[instanceName];
|
|
427
|
+
assert(instance, `missing ${instanceName}`);
|
|
428
|
+
assert(current, 'missing current wallet');
|
|
429
|
+
|
|
430
|
+
const known = findContinuingIds(current, agoricNames);
|
|
431
|
+
|
|
432
|
+
assert(known, 'could not find committee acceptance offer id');
|
|
433
|
+
|
|
434
|
+
// TODO magic string
|
|
435
|
+
const match = known.find(
|
|
436
|
+
r => r.description === 'charter member invitation',
|
|
437
|
+
);
|
|
438
|
+
assert(match, 'no offer found for charter member invitation');
|
|
439
|
+
|
|
440
|
+
return {
|
|
441
|
+
id: opts.offerId,
|
|
442
|
+
invitationSpec: {
|
|
443
|
+
source: 'continuing',
|
|
444
|
+
previousOffer: match.offerId,
|
|
445
|
+
invitationMakerName: 'VoteOnPauseOffers',
|
|
446
|
+
// ( instance, strings list, timer deadline seconds )
|
|
447
|
+
invitationArgs: harden([
|
|
448
|
+
instance,
|
|
449
|
+
opts.substring,
|
|
450
|
+
BigInt(opts.deadline * 60 + Math.round(Date.now() / 1000)),
|
|
451
|
+
]),
|
|
452
|
+
},
|
|
453
|
+
proposal: {},
|
|
454
|
+
};
|
|
455
|
+
};
|
|
456
|
+
|
|
457
|
+
await processOffer({
|
|
458
|
+
toOffer,
|
|
459
|
+
instanceName,
|
|
460
|
+
sendFrom: opts.sendFrom,
|
|
461
|
+
keyringBackend: options.optsWithGlobals().keyringBackend,
|
|
462
|
+
});
|
|
311
463
|
});
|
|
312
464
|
|
|
313
|
-
return
|
|
465
|
+
return cmd;
|
|
314
466
|
};
|