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 CHANGED
@@ -2,6 +2,79 @@
2
2
 
3
3
  If you just want to use the Agoric CLI for your own smart contract, please see the [Getting Started website](https://agoric.com/documentation/getting-started/) for information.
4
4
 
5
+ ## Relaying via IBC
6
+
7
+ The CLI integrates support for the [Confio
8
+ ts-relayer](https://github.com/confio/ts-relayer#quick-start) via the
9
+ `agoric ibc-setup` and `agoric ibc-relayer` commands.
10
+
11
+ Run `agoric start --reset -v local-chain` in a project directory. In the
12
+ meantime, you can configure the relayer (note that `--registry-from .` means to use `./registry.yaml`):
13
+
14
+ ```console
15
+ $ agoric ibc-setup init --registry-from . --src local --dest ollinet
16
+ ...
17
+ $ agoric ibc-setup keys list
18
+ ollinet: agoric1fwk40de0xu7gtlk8z858q2f5lfcqv33ml8qdg4
19
+ local: agoric1rvyry6jqmcrrm4ay9tu23rer7que8kdj4206zk
20
+ $
21
+ ```
22
+
23
+ Once your chain has booted, send some `uist` tokens to your `local` relayer
24
+ account printed above:
25
+
26
+ ```console
27
+ $ agd --home=_agstate/keys tx --keyring-backend=test bank send provision agoric1rvyry6jqmcrrm4ay9tu23rer7que8kdj4206zk 20000000uist --from=provision --chain-id=agoriclocal --yes
28
+ ...
29
+ $
30
+ ```
31
+
32
+ Go to https://ollinet.faucet.agoric.net and fund your `ollinet` relayer account
33
+ printed above with BLD/IBC toy tokens.
34
+
35
+ Check your relayer balances. Both `local` and `ollinet` relayer accounts should
36
+ show `ubld` and `uist`:
37
+
38
+ ```console
39
+ $ agoric ibc-setup balances
40
+ CHAIN AMOUNT
41
+ ollinet 74972124ubld
42
+ local 20000000uist
43
+ $
44
+ ```
45
+
46
+ Create an ICS-20 fungible token transfer channel:
47
+
48
+ ```console
49
+ $ agoric ibc-setup ics20 -v
50
+ ...
51
+ Created channel:
52
+ agoriclocal: transfer/channel-0 (connection-0)
53
+ agoricollinet-55: transfer/channel-33 (connection-12)
54
+ $
55
+ ```
56
+
57
+ Now that the channel exists, you can relay packets along it just by using:
58
+
59
+ ```console
60
+ $ agoric ibc-relayer start -v --poll 15
61
+ ```
62
+
63
+ Leave this running in the background, and use the above `transfer/channel-0` or
64
+ `transfer/channel-33` to send tokens back and forth. The following
65
+ example uses the `tx ibc-transfer transfer` command, and then
66
+ `transfer channel-0` to indicate the `transfer/channel-0` portID/channelID. It really wants you to know this is about token *transfer*.
67
+
68
+ ```console
69
+ $ agd --home=_agstate/keys tx ibc-transfer transfer --keyring-backend=test \
70
+ transfer channel-0 \
71
+ agoric1fwk40de0xu7gtlk8z858q2f5lfcqv33ml8qdg4 200uist \
72
+ --from=provision --chain-id=agoriclocal --yes
73
+ ...
74
+ # Watch the ibc-relayer send a packet and its acknowledgement, then...
75
+ $ agd query bank balances agoric1rvyry6jqmcrrm4ay9tu23rer7que8kdj4206zk
76
+ ```
77
+
5
78
  ## Developing Agoric CLI
6
79
 
7
80
  **NOTE: these steps are only for modifying the Agoric CLI. See the above for using it to create your own smart contracts.**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agoric",
3
- "version": "0.18.4",
3
+ "version": "0.18.5-dev-800c2bb.0+800c2bb",
4
4
  "description": "Manage the Agoric Javascript smart contract platform",
5
5
  "type": "module",
6
6
  "main": "src/main.js",
@@ -13,7 +13,7 @@
13
13
  "exported.js"
14
14
  ],
15
15
  "scripts": {
16
- "build": "./scripts/get-sdk-package-names.js > src/sdk-package-names.js",
16
+ "build": "node ./scripts/get-sdk-package-names.js > src/sdk-package-names.js",
17
17
  "test": "ava",
18
18
  "test:c8": "c8 $C8_OPTIONS ava --config=ava-nesm.config.js",
19
19
  "test:xs": "exit 0",
@@ -24,37 +24,44 @@
24
24
  "lint:eslint": "eslint ."
25
25
  },
26
26
  "devDependencies": {
27
- "ava": "^4.3.1",
28
- "c8": "^7.11.0"
27
+ "@agoric/deploy-script-support": "0.9.7-dev-800c2bb.0+800c2bb",
28
+ "ava": "^5.2.0",
29
+ "c8": "^7.13.0"
29
30
  },
30
31
  "dependencies": {
31
- "@agoric/access-token": "^0.4.20",
32
- "@agoric/assert": "^0.5.1",
33
- "@agoric/cache": "^0.2.4",
34
- "@agoric/casting": "^0.3.4",
35
- "@agoric/cosmic-proto": "^0.2.1",
36
- "@agoric/ertp": "^0.15.5",
37
- "@agoric/nat": "^4.1.0",
38
- "@agoric/smart-wallet": "^0.4.4",
39
- "@agoric/swingset-vat": "^0.31.0",
40
- "@agoric/zoe": "^0.25.5",
41
- "@cosmjs/crypto": "0.29.0",
42
- "@cosmjs/encoding": "0.29.0",
43
- "@cosmjs/math": "0.29.0",
44
- "@cosmjs/proto-signing": "0.29.0",
45
- "@cosmjs/stargate": "0.29.0",
46
- "@cosmjs/tendermint-rpc": "0.29.0",
47
- "@endo/bundle-source": "^2.3.1",
48
- "@endo/captp": "^2.0.15",
49
- "@endo/compartment-mapper": "^0.7.13",
50
- "@endo/far": "^0.2.11",
51
- "@endo/init": "^0.5.49",
52
- "@endo/marshal": "^0.7.5",
53
- "@endo/promise-kit": "^0.2.49",
32
+ "@agoric/access-token": "0.4.21-dev-800c2bb.0+800c2bb",
33
+ "@agoric/assert": "0.5.2-dev-800c2bb.0+800c2bb",
34
+ "@agoric/cache": "0.2.5-dev-800c2bb.0+800c2bb",
35
+ "@agoric/casting": "0.3.5-dev-800c2bb.0+800c2bb",
36
+ "@agoric/cosmic-proto": "0.2.2-dev-800c2bb.0+800c2bb",
37
+ "@agoric/ertp": "0.15.6-dev-800c2bb.0+800c2bb",
38
+ "@agoric/inter-protocol": "0.13.4-dev-800c2bb.0+800c2bb",
39
+ "@agoric/internal": "0.2.2-dev-800c2bb.0+800c2bb",
40
+ "@agoric/smart-wallet": "0.4.5-dev-800c2bb.0+800c2bb",
41
+ "@agoric/store": "0.8.6-dev-800c2bb.0+800c2bb",
42
+ "@agoric/swingset-vat": "0.31.1-dev-800c2bb.0+800c2bb",
43
+ "@agoric/vats": "0.13.3-dev-800c2bb.0+800c2bb",
44
+ "@agoric/zoe": "0.25.6-dev-800c2bb.0+800c2bb",
45
+ "@agoric/zone": "0.1.1-dev-800c2bb.0+800c2bb",
46
+ "@confio/relayer": "^0.9.0",
47
+ "@cosmjs/crypto": "^0.30.1",
48
+ "@cosmjs/encoding": "^0.30.1",
49
+ "@cosmjs/math": "^0.30.1",
50
+ "@cosmjs/proto-signing": "^0.30.1",
51
+ "@cosmjs/stargate": "^0.30.1",
52
+ "@cosmjs/tendermint-rpc": "^0.30.1",
53
+ "@endo/bundle-source": "^2.5.1",
54
+ "@endo/captp": "^3.1.1",
55
+ "@endo/compartment-mapper": "^0.8.4",
56
+ "@endo/far": "^0.2.18",
57
+ "@endo/init": "^0.5.56",
58
+ "@endo/marshal": "^0.8.5",
59
+ "@endo/nat": "^4.1.27",
60
+ "@endo/promise-kit": "^0.2.56",
54
61
  "@iarna/toml": "^2.2.3",
55
62
  "anylogger": "^0.21.0",
56
- "chalk": "^2.4.2",
57
- "commander": "^5.0.0",
63
+ "chalk": "^5.2.0",
64
+ "commander": "^10.0.0",
58
65
  "dd-trace": "^3.3.0",
59
66
  "deterministic-json": "^1.0.5",
60
67
  "esm": "agoric-labs/esm#Agoric-built",
@@ -81,5 +88,5 @@
81
88
  "timeout": "2m",
82
89
  "workerThreads": false
83
90
  },
84
- "gitHead": "636c850161d29c0368b4dec03c90e2674e8d6479"
91
+ "gitHead": "800c2bbed8ccb1e0fc24481c9f95027f95efc1fb"
85
92
  }
package/src/bin-agops.js CHANGED
@@ -1,16 +1,28 @@
1
1
  #!/usr/bin/env node
2
+ // @ts-check
3
+ // @jessie-check
4
+
2
5
  /* eslint-disable @jessie.js/no-nested-await */
3
- /* global process */
6
+ /* global fetch, setTimeout */
4
7
 
5
8
  import '@agoric/casting/node-fetch-shim.js';
6
9
  import '@endo/init';
7
10
  import '@endo/init/pre.js';
8
11
 
9
- import anylogger from 'anylogger';
10
- import { Command } from 'commander';
12
+ import { execFileSync } from 'child_process';
11
13
  import path from 'path';
14
+ import process from 'process';
15
+ import anylogger from 'anylogger';
16
+ import { Command, CommanderError, createCommand } from 'commander';
17
+ import { makeOracleCommand } from './commands/oracle.js';
18
+ import { makeEconomicCommiteeCommand } from './commands/ec.js';
12
19
  import { makePsmCommand } from './commands/psm.js';
20
+ import { makeReserveCommand } from './commands/reserve.js';
21
+ import { makeVaultsCommand } from './commands/vaults.js';
13
22
  import { makePerfCommand } from './commands/perf.js';
23
+ import { makeInterCommand } from './commands/inter.js';
24
+ import { makeAuctionCommand } from './commands/auction.js';
25
+ import { makeTestCommand } from './commands/test-upgrade.js';
14
26
 
15
27
  const logger = anylogger('agops');
16
28
  const progname = path.basename(process.argv[1]);
@@ -18,7 +30,57 @@ const progname = path.basename(process.argv[1]);
18
30
  const program = new Command();
19
31
  program.name(progname).version('unversioned');
20
32
 
21
- program.addCommand(await makePsmCommand(logger));
22
- program.addCommand(await makePerfCommand(logger));
33
+ program.addCommand(makeOracleCommand(logger));
34
+ program.addCommand(makeEconomicCommiteeCommand(logger));
35
+ program.addCommand(makePerfCommand(logger));
36
+ program.addCommand(makePsmCommand(logger));
37
+ program.addCommand(makeVaultsCommand(logger));
38
+
39
+ /**
40
+ * XXX Threading I/O powers has gotten a bit jumbled.
41
+ *
42
+ * Perhaps a more straightforward approach would be:
43
+ *
44
+ * - makeTUI({ stdout, stderr, logger })
45
+ * where tui.show(data) prints data as JSON to stdout
46
+ * and tui.warn() and tui.error() log ad-hoc to stderr
47
+ * - makeQueryClient({ fetch })
48
+ * with q.withConfig(networkConfig)
49
+ * and q.vstorage.get('published...') (no un-marshaling)
50
+ * and q.pollBlocks(), q.pollTx()
51
+ * also, printing the progress message should be done
52
+ * in the lookup callback
53
+ * - makeBoardClient(queryClient)
54
+ * with b.readLatestHead('published...')
55
+ * - makeKeyringNames({ execFileSync })
56
+ * with names.lookup('gov1') -> 'agoric1...'
57
+ * and names.withBackend('test')
58
+ * and names.withHome('~/.agoric')
59
+ * - makeSigner({ execFileSync })
60
+ * signer.sendSwingsetTx()
61
+ */
62
+ const procIO = {
63
+ env: { ...process.env },
64
+ stdout: process.stdout,
65
+ stderr: process.stderr,
66
+ createCommand,
67
+ execFileSync,
68
+ now: () => Date.now(),
69
+ setTimeout,
70
+ };
71
+
72
+ program.addCommand(makeReserveCommand(logger, procIO));
73
+ program.addCommand(makeAuctionCommand(logger, { ...procIO, fetch }));
74
+ program.addCommand(makeInterCommand(procIO, { fetch }));
75
+ program.addCommand(makeTestCommand(procIO, { fetch }));
23
76
 
24
- await program.parseAsync(process.argv);
77
+ try {
78
+ await program.parseAsync(process.argv);
79
+ } catch (err) {
80
+ if (err instanceof CommanderError) {
81
+ console.error(err.message);
82
+ } else {
83
+ console.error(err); // CRASH! show stack trace
84
+ }
85
+ process.exit(1);
86
+ }
@@ -30,8 +30,8 @@ const Stake = /** @type {const} */ ({
30
30
  symbol: 'BLD',
31
31
  });
32
32
  const Stable = /** @type {const} */ ({
33
- name: 'Agoric Stable Local Currency',
34
- description: 'The stable local currency used by the Agoric chain',
33
+ name: 'Agoric stable token',
34
+ description: 'The stable token used by the Agoric chain',
35
35
  denom_units: [
36
36
  {
37
37
  denom: 'uist',
@@ -73,6 +73,8 @@ export const ORIG_BLOCK_CADENCE_S = 5;
73
73
  export const ORIG_SIGNED_BLOCKS_WINDOW = 100;
74
74
  export const SIGNED_BLOCKS_WINDOW_BASE_MULTIPLIER = 100;
75
75
 
76
+ export const DEFAULT_CHAIN_ID = 'agoriclocal';
77
+ export const DEFAULT_ROSETTA_PORT = 8080;
76
78
  export const DEFAULT_GRPC_PORT = 9090;
77
79
  export const DEFAULT_RPC_PORT = 26657;
78
80
  export const DEFAULT_PROM_PORT = 26660;
@@ -84,6 +86,9 @@ export function finishCosmosApp({
84
86
  enableCors,
85
87
  exportMetrics,
86
88
  portNum = `${DEFAULT_RPC_PORT}`,
89
+ chainId = DEFAULT_CHAIN_ID,
90
+ enableRosetta = true,
91
+ rosettaPort = `${DEFAULT_ROSETTA_PORT}`,
87
92
  }) {
88
93
  const rpcPort = Number(portNum);
89
94
  const app = TOML.parse(appToml);
@@ -117,6 +122,18 @@ export function finishCosmosApp({
117
122
  app.telemetry['prometheus-retention-time'] = 60;
118
123
  }
119
124
 
125
+ // Optionally enable the rosetta service
126
+ if (enableRosetta) {
127
+ app.rosetta.enable = enableRosetta;
128
+ app.rosetta.network = chainId;
129
+ app.rosetta.retries = 30;
130
+ }
131
+
132
+ if (rosettaPort !== `${DEFAULT_ROSETTA_PORT}`) {
133
+ // Rosetta doesn't want a scheme
134
+ app.rosetta.address = `0.0.0.0:${rosettaPort}`;
135
+ }
136
+
120
137
  return TOML.stringify(app);
121
138
  }
122
139
 
@@ -0,0 +1,170 @@
1
+ /* eslint-disable @jessie.js/no-nested-await */
2
+ // @ts-check
3
+ /* eslint-disable func-names */
4
+ import { InvalidArgumentError } from 'commander';
5
+ import { makeRpcUtils } from '../lib/rpc.js';
6
+ import { outputActionAndHint } from '../lib/wallet.js';
7
+
8
+ const { Fail } = assert;
9
+
10
+ /** @typedef {import('@agoric/governance/src/contractGovernance/typedParamManager.js').ParamTypesMap} ParamTypesMap */
11
+ /** @template M @typedef {import('@agoric/governance/src/contractGovernance/typedParamManager.js').ParamTypesMapFromRecord<M>} ParamTypesMapFromRecord */
12
+
13
+ /**
14
+ * @template {ParamTypesMap} M
15
+ * @typedef {{
16
+ * [K in keyof M]: ParamValueForType<M[K]>
17
+ * }} ParamValues
18
+ */
19
+
20
+ /** @typedef {ReturnType<import('@agoric/inter-protocol/src/auction/params.js').makeAuctioneerParams>} AuctionParamRecord */
21
+ /** @typedef {ParamValues<ParamTypesMapFromRecord<AuctionParamRecord>>} AuctionParams */
22
+
23
+ /**
24
+ * @param {import('anylogger').Logger} _logger
25
+ * @param {{
26
+ * createCommand: typeof import('commander').createCommand,
27
+ * fetch: typeof window.fetch,
28
+ * stdout: Pick<import('stream').Writable, 'write'>,
29
+ * stderr: Pick<import('stream').Writable, 'write'>,
30
+ * now: () => number,
31
+ * }} io
32
+ */
33
+ export const makeAuctionCommand = (
34
+ _logger,
35
+ { createCommand, stdout, stderr, fetch, now },
36
+ ) => {
37
+ const auctioneer = createCommand('auctioneer').description(
38
+ 'Auctioneer commands',
39
+ );
40
+
41
+ auctioneer
42
+ .command('proposeParamChange')
43
+ .description('propose a change to start frequency')
44
+ .option(
45
+ '--start-frequency <seconds>',
46
+ 'how often to start auctions',
47
+ BigInt,
48
+ )
49
+ .option('--price-lock-period <seconds>', 'price lock period', BigInt)
50
+ .option('--clock-step <seconds>', 'descending clock frequency', BigInt)
51
+ .option(
52
+ '--starting-rate <basis-points>',
53
+ 'relative to oracle: 999 = 1bp discount',
54
+ BigInt,
55
+ )
56
+ .option('--lowest-rate <basis-points>', 'lower limit for discount', BigInt)
57
+ .option(
58
+ '--discount-step <basis-points>',
59
+ 'descending clock step size',
60
+ BigInt,
61
+ )
62
+ .option(
63
+ '--discount-step <integer>',
64
+ 'proposed value (basis points)',
65
+ BigInt,
66
+ )
67
+ .requiredOption(
68
+ '--charterAcceptOfferId <string>',
69
+ 'offer that had continuing invitation result',
70
+ )
71
+ .option('--offer-id <string>', 'Offer id', String, `propose-${Date.now()}`)
72
+ .option(
73
+ '--deadline <minutes>',
74
+ 'minutes from now to close the vote',
75
+ Number,
76
+ 1,
77
+ )
78
+ .action(
79
+ /**
80
+ *
81
+ * @param {{
82
+ * charterAcceptOfferId: string,
83
+ * startFrequency?: bigint,
84
+ * clockStep?: bigint,
85
+ * startingRate?: bigint,
86
+ * lowestRate?: bigint,
87
+ * discountStep?: bigint,
88
+ * priceLockPeriod?: bigint,
89
+ * offerId: string,
90
+ * deadline: number,
91
+ * }} opts
92
+ */
93
+ async opts => {
94
+ const { agoricNames, readLatestHead } = await makeRpcUtils({ fetch });
95
+
96
+ /** @type {{ current: AuctionParamRecord }} */
97
+ // @ts-expect-error XXX should runtime check?
98
+ const { current } = await readLatestHead(
99
+ `published.auction.governance`,
100
+ );
101
+
102
+ const {
103
+ AuctionStartDelay: {
104
+ value: { timerBrand },
105
+ },
106
+ } = current;
107
+ timerBrand || Fail`no timer brand?`;
108
+
109
+ /**
110
+ * typed param manager requires RelativeTimeRecord
111
+ * but TimeMath.toRel prodocues a RelativeTime (which may be a bare bigint).
112
+ *
113
+ * @param {bigint} relValue
114
+ * @returns {import('@agoric/time/src/types').RelativeTimeRecord}
115
+ */
116
+ const toRel = relValue => ({ timerBrand, relValue });
117
+
118
+ /** @type {Partial<AuctionParams>} */
119
+ const params = {
120
+ ...(opts.startFrequency && {
121
+ StartFrequency: toRel(opts.startFrequency),
122
+ }),
123
+ ...(opts.clockStep && { ClockStep: toRel(opts.clockStep) }),
124
+ ...(opts.startingRate && { StartingRate: opts.startingRate }),
125
+ ...(opts.lowestRate && { LowestRate: opts.lowestRate }),
126
+ ...(opts.discountStep && { DiscountStep: opts.discountStep }),
127
+ ...(opts.priceLockPeriod && {
128
+ PriceLockPeriod: toRel(opts.priceLockPeriod),
129
+ }),
130
+ };
131
+
132
+ if (Object.keys(params).length === 0) {
133
+ throw new InvalidArgumentError(`no parameters given`);
134
+ }
135
+
136
+ const instance = agoricNames.instance.auctioneer;
137
+ instance || Fail`missing auctioneer in names`;
138
+
139
+ const t0 = now();
140
+ const deadline = BigInt(Math.round(t0 / 1000) + 60 * opts.deadline);
141
+
142
+ /** @type {import('@agoric/inter-protocol/src/econCommitteeCharter.js').ParamChangesOfferArgs} */
143
+ const offerArgs = {
144
+ deadline,
145
+ params,
146
+ instance,
147
+ path: { paramPath: { key: 'governedParams' } },
148
+ };
149
+
150
+ /** @type {import('@agoric/smart-wallet/src/offers.js').OfferSpec} */
151
+ const offer = {
152
+ id: opts.offerId,
153
+ invitationSpec: {
154
+ source: 'continuing',
155
+ previousOffer: opts.charterAcceptOfferId,
156
+ invitationMakerName: 'VoteOnParamChange',
157
+ },
158
+ offerArgs,
159
+ proposal: {},
160
+ };
161
+
162
+ outputActionAndHint(
163
+ { method: 'executeOffer', offer },
164
+ { stdout, stderr },
165
+ );
166
+ },
167
+ );
168
+
169
+ return auctioneer;
170
+ };