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.
@@ -0,0 +1,212 @@
1
+ /* eslint-disable no-await-in-loop */
2
+ /* eslint-disable @jessie.js/no-nested-await */
3
+ // @ts-check
4
+ /* eslint-disable func-names */
5
+ /* global fetch */
6
+ import { Fail } from '@agoric/assert';
7
+ import { Nat } from '@endo/nat';
8
+ import { Command } from 'commander';
9
+ import { inspect } from 'util';
10
+ import { makeRpcUtils, storageHelper } from '../lib/rpc.js';
11
+ import { getCurrent, outputAction } from '../lib/wallet.js';
12
+
13
+ // XXX support other decimal places
14
+ const COSMOS_UNIT = 1_000_000n;
15
+ const scaleDecimals = num => BigInt(num * Number(COSMOS_UNIT));
16
+
17
+ /**
18
+ * @param {import('anylogger').Logger} logger
19
+ */
20
+ export const makeOracleCommand = logger => {
21
+ const oracle = new Command('oracle').description('Oracle commands').usage(
22
+ `
23
+ WALLET=my-wallet
24
+ export AGORIC_NET=ollinet
25
+
26
+ # provision wallet if necessary
27
+ agd keys add $WALLET
28
+ # provision with faucet, e.g.
29
+ open https://ollinet.faucet.agoric.net/ # and paste the key and choose client: smart-wallet
30
+
31
+ # confirm funds
32
+ agoric wallet list
33
+ agoric wallet show —from $WALLET
34
+
35
+ # prepare an offer to send
36
+ # (offerId is optional but best to specify as each must be higher than the last and the default value is a huge number)
37
+ agops oracle accept --offerId 12 > offer-12.json
38
+
39
+ # sign and send
40
+ agoric wallet send --from $WALLET --offer offer-12.json
41
+ `,
42
+ );
43
+
44
+ const rpcTools = async () => {
45
+ const utils = await makeRpcUtils({ fetch });
46
+
47
+ const lookupPriceAggregatorInstance = ([brandIn, brandOut]) => {
48
+ const name = `${brandIn}-${brandOut} price feed`;
49
+ const instance = utils.agoricNames.instance[name];
50
+ if (!instance) {
51
+ logger.debug('known instances:', utils.agoricNames.instance);
52
+ throw Error(`Unknown instance ${name}`);
53
+ }
54
+ return instance;
55
+ };
56
+
57
+ return { ...utils, lookupPriceAggregatorInstance };
58
+ };
59
+
60
+ oracle
61
+ .command('accept')
62
+ .description('accept invitation to operate an oracle')
63
+ .requiredOption(
64
+ '--pair [brandIn.brandOut]',
65
+ 'token pair (brandIn.brandOut)',
66
+ s => s.split('.'),
67
+ ['ATOM', 'USD'],
68
+ )
69
+ .option(
70
+ '--offerId <string>',
71
+ 'Offer id',
72
+ String,
73
+ `oracleAccept-${Date.now()}`,
74
+ )
75
+ .action(async function (opts) {
76
+ const { lookupPriceAggregatorInstance } = await rpcTools();
77
+ const instance = lookupPriceAggregatorInstance(opts.pair);
78
+
79
+ /** @type {import('@agoric/smart-wallet/src/offers.js').OfferSpec} */
80
+ const offer = {
81
+ id: opts.offerId,
82
+ invitationSpec: {
83
+ source: 'purse',
84
+ instance,
85
+ description: 'oracle invitation',
86
+ },
87
+ proposal: {},
88
+ };
89
+
90
+ outputAction({
91
+ method: 'executeOffer',
92
+ offer,
93
+ });
94
+
95
+ console.warn('Now execute the prepared offer');
96
+ });
97
+
98
+ oracle
99
+ .command('pushPrice')
100
+ .description('add a current price sample to a priceAggregator')
101
+ .option('--offerId <string>', 'Offer id', String, `pushPrice-${Date.now()}`)
102
+ .requiredOption(
103
+ '--oracleAdminAcceptOfferId <number>',
104
+ 'offer that had continuing invitation result',
105
+ Number,
106
+ )
107
+ .requiredOption('--price <number>', 'price (format TODO)', String)
108
+ .action(async function (opts) {
109
+ /** @type {import('@agoric/smart-wallet/src/offers.js').OfferSpec} */
110
+ const offer = {
111
+ id: opts.offerId,
112
+ invitationSpec: {
113
+ source: 'continuing',
114
+ previousOffer: opts.oracleAdminAcceptOfferId,
115
+ invitationMakerName: 'PushPrice',
116
+ invitationArgs: harden([opts.price]),
117
+ },
118
+ proposal: {},
119
+ };
120
+
121
+ outputAction({
122
+ method: 'executeOffer',
123
+ offer,
124
+ });
125
+
126
+ console.warn('Now execute the prepared offer');
127
+ });
128
+
129
+ oracle
130
+ .command('pushPriceRound')
131
+ .description('add a price for a round to a fluxAggregator')
132
+ .option(
133
+ '--offerId <string>',
134
+ 'Offer id',
135
+ String,
136
+ `pushPriceRound-${Date.now()}`,
137
+ )
138
+ .requiredOption(
139
+ '--oracleAdminAcceptOfferId <string>',
140
+ 'offer that had continuing invitation result',
141
+ String,
142
+ )
143
+ .requiredOption('--price <number>', 'price', Number)
144
+ .option('--roundId <number>', 'round', Number)
145
+ .action(async function (opts) {
146
+ const unitPrice = scaleDecimals(opts.price);
147
+ const roundId = 'roundId' in opts ? Nat(opts.roundId) : undefined;
148
+ /** @type {import('@agoric/smart-wallet/src/offers.js').OfferSpec} */
149
+ const offer = {
150
+ id: opts.offerId,
151
+ invitationSpec: {
152
+ source: 'continuing',
153
+ previousOffer: opts.oracleAdminAcceptOfferId,
154
+ invitationMakerName: 'PushPrice',
155
+ invitationArgs: harden([{ unitPrice, roundId }]),
156
+ },
157
+ proposal: {},
158
+ };
159
+
160
+ outputAction({
161
+ method: 'executeOffer',
162
+ offer,
163
+ });
164
+
165
+ console.warn('Now execute the prepared offer');
166
+ });
167
+
168
+ oracle
169
+ .command('find-continuing-id')
170
+ .description('print id of specified oracle continuing invitation')
171
+ .requiredOption('--from <address>', 'from address', String)
172
+ .action(async opts => {
173
+ const { readLatestHead } = await makeRpcUtils({ fetch });
174
+ const current = await getCurrent(opts.from, { readLatestHead });
175
+
176
+ const { offerToUsedInvitation: entries } = /** @type {any} */ (current);
177
+ Array.isArray(entries) || Fail`entries must be an array: ${entries}`;
178
+
179
+ for (const [offerId, { value }] of entries) {
180
+ /** @type {{ description: string, instance: unknown }[]} */
181
+ const [{ description }] = value;
182
+ if (description === 'oracle invitation') {
183
+ console.log(offerId);
184
+ return;
185
+ }
186
+ }
187
+
188
+ console.error('No continuing ids found');
189
+ });
190
+
191
+ oracle
192
+ .command('query')
193
+ .description('return current aggregated (median) price')
194
+ .requiredOption(
195
+ '--pair [brandIn.brandOut]',
196
+ 'token pair (brandIn.brandOut)',
197
+ s => s.split('.'),
198
+ ['ATOM', 'USD'],
199
+ )
200
+ .action(async function (opts) {
201
+ const { pair } = opts;
202
+ const { vstorage, fromBoard } = await rpcTools();
203
+
204
+ const capDataStr = await vstorage.readLatest(
205
+ `published.priceFeed.${pair[0]}-${pair[1]}_price_feed`,
206
+ );
207
+ const capDatas = storageHelper.unserializeTxt(capDataStr, fromBoard);
208
+
209
+ console.log(inspect(capDatas[0], { depth: 10, colors: true }));
210
+ });
211
+ return oracle;
212
+ };
@@ -12,19 +12,32 @@ import {
12
12
  import { Command } from 'commander';
13
13
  import fs from 'fs';
14
14
  import { exit } from 'process';
15
+ import { slotToRemotable } from '@agoric/internal/src/storage-test-utils.js';
16
+ import { boardSlottingMarshaller } from '@agoric/vats/tools/board-utils.js';
15
17
  import { makeLeaderOptions } from '../lib/casting.js';
16
- import { execSwingsetTransaction, normalizeAddress } from '../lib/chain.js';
18
+ import {
19
+ execSwingsetTransaction,
20
+ normalizeAddressWithOptions,
21
+ } from '../lib/chain.js';
17
22
  import { networkConfig } from '../lib/rpc.js';
18
23
 
19
24
  // tight for perf testing but less than this tends to hang.
20
25
  const SLEEP_SECONDS = 0.1;
21
26
 
22
27
  /**
23
- *
24
28
  * @param {import('anylogger').Logger} logger
25
29
  */
26
- export const makePerfCommand = async logger => {
27
- const perf = new Command('perf').description('Performance testing commands');
30
+ export const makePerfCommand = logger => {
31
+ const perf = new Command('perf')
32
+ .description('Performance testing commands')
33
+ .option(
34
+ '--keyring-backend <string>',
35
+ 'Select keyring’s backend (os|file|kwallet|pass|test|memory) (default "os")',
36
+ 'os',
37
+ )
38
+ .option('--home <string>', 'directory for config and data');
39
+ const normalizeAddress = literalOrName =>
40
+ normalizeAddressWithOptions(literalOrName, perf.opts());
28
41
 
29
42
  perf
30
43
  .command('satisfaction')
@@ -34,21 +47,18 @@ export const makePerfCommand = async logger => {
34
47
  )
35
48
  .description('filename of prepared offer')
36
49
  .requiredOption(
37
- '--from [address]',
50
+ '--from <address>',
38
51
  'address literal or name',
39
52
  normalizeAddress,
40
53
  )
41
- .option(
42
- '--keyring-backend [string]',
43
- 'Select keyring’s backend (os|file|kwallet|pass|test|memory) (default "os")',
44
- 'os',
45
- )
46
- .option('--home [string]', 'directory for config and data')
47
- .action(async function () {
48
- const opts = this.opts();
49
- logger.warn({ opts });
50
- const payloadStr = await fs.readFileSync(opts.executeOffer).toString();
51
- const { offer } = JSON.parse(JSON.parse(payloadStr).body);
54
+ .action(async function (opts) {
55
+ const sharedOpts = perf.opts();
56
+ logger.warn({ sharedOpts, opts });
57
+ const payloadStr = fs.readFileSync(opts.executeOffer).toString();
58
+ const payloadCapData = JSON.parse(payloadStr);
59
+ const unserializer = boardSlottingMarshaller(slotToRemotable);
60
+ const obj = unserializer.fromCapData(payloadCapData);
61
+ const { offer } = obj;
52
62
  const { id: offerId } = offer;
53
63
 
54
64
  const spec = `:published.wallet.${opts.from}`;
@@ -85,14 +95,14 @@ export const makePerfCommand = async logger => {
85
95
  void watchForSatisfied();
86
96
 
87
97
  // now execute
88
- let cmd = `wallet-action --allow-spend "$(cat ${opts.executeOffer})"`;
89
- if (opts.keyringBackend) {
90
- cmd = cmd.concat(' --keyring-backend ', opts.keyringBackend);
98
+ const cmd = ['wallet-action', '--allow-spend', payloadStr];
99
+ if (sharedOpts.keyringBackend) {
100
+ cmd.push(`--keyring-backend=${sharedOpts.keyringBackend}`);
91
101
  }
92
- if (opts.home) {
93
- cmd = cmd.concat(' --home ', opts.home);
102
+ if (sharedOpts.home) {
103
+ cmd.push(`--home=${sharedOpts.home}`);
94
104
  }
95
- execSwingsetTransaction(cmd, networkConfig, opts.from);
105
+ execSwingsetTransaction(cmd, { from: opts.from, ...networkConfig });
96
106
  });
97
107
 
98
108
  return perf;