agoric 0.21.2-dev-d603b6c.0 → 0.21.2-dev-02c06c4.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agoric",
3
- "version": "0.21.2-dev-d603b6c.0+d603b6c",
3
+ "version": "0.21.2-dev-02c06c4.0+02c06c4",
4
4
  "description": "Manage the Agoric Javascript smart contract platform",
5
5
  "type": "module",
6
6
  "main": "src/main.js",
@@ -29,28 +29,29 @@
29
29
  "lint:eslint": "eslint ."
30
30
  },
31
31
  "devDependencies": {
32
- "@agoric/cosmic-swingset": "0.41.4-dev-d603b6c.0+d603b6c",
33
- "@agoric/deploy-script-support": "0.10.4-dev-d603b6c.0+d603b6c",
32
+ "@agoric/cosmic-swingset": "0.41.4-dev-02c06c4.0+02c06c4",
33
+ "@agoric/deploy-script-support": "0.10.4-dev-02c06c4.0+02c06c4",
34
34
  "ava": "^5.3.0",
35
35
  "c8": "^9.1.0",
36
36
  "dd-trace": "^4.11.1"
37
37
  },
38
38
  "dependencies": {
39
- "@agoric/access-token": "0.4.22-dev-d603b6c.0+d603b6c",
40
- "@agoric/cache": "0.3.3-dev-d603b6c.0+d603b6c",
41
- "@agoric/casting": "0.4.3-dev-d603b6c.0+d603b6c",
42
- "@agoric/cosmic-proto": "0.4.1-dev-d603b6c.0+d603b6c",
43
- "@agoric/ertp": "0.16.3-dev-d603b6c.0+d603b6c",
44
- "@agoric/governance": "0.10.4-dev-d603b6c.0+d603b6c",
45
- "@agoric/inter-protocol": "0.16.2-dev-d603b6c.0+d603b6c",
46
- "@agoric/internal": "0.3.3-dev-d603b6c.0+d603b6c",
47
- "@agoric/network": "0.1.1-dev-d603b6c.0+d603b6c",
48
- "@agoric/smart-wallet": "0.5.4-dev-d603b6c.0+d603b6c",
49
- "@agoric/store": "0.9.3-dev-d603b6c.0+d603b6c",
50
- "@agoric/swingset-vat": "0.32.3-dev-d603b6c.0+d603b6c",
51
- "@agoric/vats": "0.15.2-dev-d603b6c.0+d603b6c",
52
- "@agoric/zoe": "0.26.3-dev-d603b6c.0+d603b6c",
53
- "@agoric/zone": "0.2.3-dev-d603b6c.0+d603b6c",
39
+ "@agoric/access-token": "0.4.22-dev-02c06c4.0+02c06c4",
40
+ "@agoric/cache": "0.3.3-dev-02c06c4.0+02c06c4",
41
+ "@agoric/casting": "0.4.3-dev-02c06c4.0+02c06c4",
42
+ "@agoric/client-utils": "0.1.1-dev-02c06c4.0+02c06c4",
43
+ "@agoric/cosmic-proto": "0.4.1-dev-02c06c4.0+02c06c4",
44
+ "@agoric/ertp": "0.16.3-dev-02c06c4.0+02c06c4",
45
+ "@agoric/governance": "0.10.4-dev-02c06c4.0+02c06c4",
46
+ "@agoric/inter-protocol": "0.16.2-dev-02c06c4.0+02c06c4",
47
+ "@agoric/internal": "0.3.3-dev-02c06c4.0+02c06c4",
48
+ "@agoric/network": "0.1.1-dev-02c06c4.0+02c06c4",
49
+ "@agoric/smart-wallet": "0.5.4-dev-02c06c4.0+02c06c4",
50
+ "@agoric/store": "0.9.3-dev-02c06c4.0+02c06c4",
51
+ "@agoric/swingset-vat": "0.32.3-dev-02c06c4.0+02c06c4",
52
+ "@agoric/vats": "0.15.2-dev-02c06c4.0+02c06c4",
53
+ "@agoric/zoe": "0.26.3-dev-02c06c4.0+02c06c4",
54
+ "@agoric/zone": "0.2.3-dev-02c06c4.0+02c06c4",
54
55
  "@confio/relayer": "^0.11.3",
55
56
  "@cosmjs/crypto": "^0.32.3",
56
57
  "@cosmjs/encoding": "^0.32.3",
@@ -99,7 +100,7 @@
99
100
  "workerThreads": false
100
101
  },
101
102
  "typeCoverage": {
102
- "atLeast": 77.44
103
+ "atLeast": 77.45
103
104
  },
104
- "gitHead": "d603b6c9c4d7b214dcd1a73f15a347c48e80b8bb"
105
+ "gitHead": "02c06c489677233c0daa112284d16c314aff97c6"
105
106
  }
@@ -1,15 +1,18 @@
1
1
  // @ts-check
2
-
2
+ /* eslint-env node */
3
3
  import { InvalidArgumentError } from 'commander';
4
4
  import { Fail } from '@endo/errors';
5
- import { makeRpcUtils } from '../lib/rpc.js';
5
+ import { makeVstorageKit } from '@agoric/client-utils';
6
6
  import { outputActionAndHint } from '../lib/wallet.js';
7
+ import { getNetworkConfig } from '../lib/network-config.js';
7
8
 
8
9
  /**
9
10
  * @import {ParamTypesMap, ParamTypesMapFromRecord} from '@agoric/governance/src/contractGovernance/typedParamManager.js'
10
11
  * @import {ParamValueForType} from '@agoric/governance/src/types.js'
11
12
  */
12
13
 
14
+ const networkConfig = await getNetworkConfig({ env: process.env, fetch });
15
+
13
16
  /**
14
17
  * @template {ParamTypesMap} M
15
18
  * @typedef {{
@@ -86,7 +89,10 @@ export const makeAuctionCommand = (
86
89
  * }} opts
87
90
  */
88
91
  async opts => {
89
- const { agoricNames, readLatestHead } = await makeRpcUtils({ fetch });
92
+ const { agoricNames, readLatestHead } = await makeVstorageKit(
93
+ { fetch },
94
+ networkConfig,
95
+ );
90
96
 
91
97
  /** @type {{ current: AuctionParamRecord }} */
92
98
  // @ts-expect-error XXX should runtime check?
@@ -1,10 +1,11 @@
1
1
  // @ts-check
2
2
  /* eslint-disable func-names */
3
- /* global globalThis, process, setTimeout */
3
+ /* eslint-env node */
4
+ import { makeVstorageKit } from '@agoric/client-utils';
4
5
  import { execFileSync as execFileSyncAmbient } from 'child_process';
5
6
  import { Command, CommanderError } from 'commander';
6
7
  import { normalizeAddressWithOptions, pollBlocks } from '../lib/chain.js';
7
- import { getNetworkConfig, makeRpcUtils } from '../lib/rpc.js';
8
+ import { getNetworkConfig } from '../lib/network-config.js';
8
9
  import {
9
10
  findContinuingIds,
10
11
  getCurrent,
@@ -25,6 +26,8 @@ const collectValues = (val, memo) => {
25
26
 
26
27
  const defaultKeyring = process.env.AGORIC_KEYRING_BACKEND || 'test';
27
28
 
29
+ const networkConfig = await getNetworkConfig({ env: process.env, fetch });
30
+
28
31
  /**
29
32
  * @param {import('anylogger').Logger} _logger
30
33
  * @param {{
@@ -40,10 +43,9 @@ export const makeGovCommand = (_logger, io = {}) => {
40
43
  const {
41
44
  // Allow caller to provide access explicitly, but
42
45
  // default to conventional ambient IO facilities.
43
- env = process.env,
44
46
  stdout = process.stdout,
45
47
  stderr = process.stderr,
46
- fetch = globalThis.fetch,
48
+ fetch = global.fetch,
47
49
  execFileSync = execFileSyncAmbient,
48
50
  delay = ms => new Promise(resolve => setTimeout(resolve, ms)),
49
51
  } = io;
@@ -89,14 +91,13 @@ export const makeGovCommand = (_logger, io = {}) => {
89
91
  * keyringBackend: string,
90
92
  * instanceName?: string,
91
93
  * }} detail
92
- * @param {Awaited<ReturnType<makeRpcUtils>>} [optUtils]
94
+ * @param {Awaited<ReturnType<makeVstorageKit>>} [optUtils]
93
95
  */
94
96
  const processOffer = async function (
95
97
  { toOffer, sendFrom, keyringBackend },
96
98
  optUtils,
97
99
  ) {
98
- const networkConfig = await getNetworkConfig(env);
99
- const utils = await (optUtils || makeRpcUtils({ fetch }));
100
+ const utils = await (optUtils || makeVstorageKit({ fetch }, networkConfig));
100
101
  const { agoricNames, readLatestHead } = utils;
101
102
 
102
103
  assert(keyringBackend, 'missing keyring-backend option');
@@ -264,7 +265,10 @@ export const makeGovCommand = (_logger, io = {}) => {
264
265
  )
265
266
  .requiredOption('--for <string>', 'description of the invitation')
266
267
  .action(async opts => {
267
- const { agoricNames, readLatestHead } = await makeRpcUtils({ fetch });
268
+ const { agoricNames, readLatestHead } = await makeVstorageKit(
269
+ { fetch },
270
+ networkConfig,
271
+ );
268
272
  const current = await getCurrent(opts.from, { readLatestHead });
269
273
 
270
274
  const known = findContinuingIds(current, agoricNames);
@@ -290,7 +294,10 @@ export const makeGovCommand = (_logger, io = {}) => {
290
294
  normalizeAddress,
291
295
  )
292
296
  .action(async opts => {
293
- const { agoricNames, readLatestHead } = await makeRpcUtils({ fetch });
297
+ const { agoricNames, readLatestHead } = await makeVstorageKit(
298
+ { fetch },
299
+ networkConfig,
300
+ );
294
301
  const current = await getCurrent(opts.from, { readLatestHead });
295
302
 
296
303
  const found = findContinuingIds(current, agoricNames);
@@ -326,7 +333,7 @@ export const makeGovCommand = (_logger, io = {}) => {
326
333
  normalizeAddress,
327
334
  )
328
335
  .action(async function (opts, options) {
329
- const utils = await makeRpcUtils({ fetch });
336
+ const utils = await makeVstorageKit({ fetch }, networkConfig);
330
337
  const { readLatestHead } = utils;
331
338
 
332
339
  const info = await readLatestHead(
@@ -4,26 +4,20 @@
4
4
  */
5
5
 
6
6
  // @ts-check
7
- import { CommanderError, InvalidArgumentError } from 'commander';
8
- // TODO: should get M from endo https://github.com/Agoric/agoric-sdk/issues/7090
7
+ import { makeWalletUtils } from '@agoric/client-utils';
9
8
  import { makeOfferSpecShape } from '@agoric/inter-protocol/src/auction/auctionBook.js';
10
9
  import { Offers } from '@agoric/inter-protocol/src/clientSupport.js';
11
10
  import { objectMap } from '@agoric/internal';
12
- import { M, matches } from '@agoric/store';
13
-
11
+ import { M, matches } from '@endo/patterns';
12
+ import { CommanderError, InvalidArgumentError } from 'commander';
14
13
  import { normalizeAddressWithOptions, pollBlocks } from '../lib/chain.js';
14
+ import { getCurrent, outputActionAndHint, sendAction } from '../lib/wallet.js';
15
15
  import {
16
16
  asBoardRemote,
17
17
  bigintReplacer,
18
18
  makeAmountFormatter,
19
19
  } from '../lib/format.js';
20
- import { getNetworkConfig } from '../lib/rpc.js';
21
- import {
22
- getCurrent,
23
- makeWalletUtils,
24
- outputActionAndHint,
25
- sendAction,
26
- } from '../lib/wallet.js';
20
+ import { getNetworkConfig } from '../lib/network-config.js';
27
21
 
28
22
  const { values } = Object;
29
23
 
@@ -238,8 +232,8 @@ export const makeInterCommand = (
238
232
  try {
239
233
  // XXX pass fetch to getNetworkConfig() explicitly
240
234
  // await null above makes this await safe
241
- const networkConfig = await getNetworkConfig(env);
242
- return makeWalletUtils({ fetch, execFileSync, delay }, networkConfig);
235
+ const networkConfig = await getNetworkConfig({ env, fetch });
236
+ return makeWalletUtils({ fetch, delay }, networkConfig);
243
237
  } catch (err) {
244
238
  // CommanderError is a class constructor, and so
245
239
  // must be invoked with `new`.
@@ -334,7 +328,7 @@ inter auction status
334
328
  * @param {string} from
335
329
  * @param {import('@agoric/smart-wallet/src/offers.js').OfferSpec} offer
336
330
  * @param {Awaited<ReturnType<tryMakeUtils>>} tools
337
- * @param {boolean?} dryRun
331
+ * @param {boolean | undefined} dryRun
338
332
  */
339
333
  const placeBid = async (from, offer, tools, dryRun = false) => {
340
334
  const { networkConfig, agoricNames, pollOffer } = tools;
@@ -1,6 +1,11 @@
1
1
  // @ts-check
2
2
  /* eslint-disable func-names */
3
3
  /* eslint-env node */
4
+ import {
5
+ makeVstorageKit,
6
+ makeWalletUtils,
7
+ storageHelper,
8
+ } from '@agoric/client-utils';
4
9
  import { Offers } from '@agoric/inter-protocol/src/clientSupport.js';
5
10
  import { oracleBrandFeedName } from '@agoric/inter-protocol/src/proposals/utils.js';
6
11
  import { Fail } from '@endo/errors';
@@ -9,15 +14,14 @@ import * as cp from 'child_process';
9
14
  import { Command } from 'commander';
10
15
  import { inspect } from 'util';
11
16
  import { normalizeAddressWithOptions } from '../lib/chain.js';
12
- import { bigintReplacer } from '../lib/format.js';
13
- import { getNetworkConfig, makeRpcUtils, storageHelper } from '../lib/rpc.js';
17
+ import { getNetworkConfig } from '../lib/network-config.js';
14
18
  import {
15
19
  getCurrent,
16
- makeWalletUtils,
17
20
  outputAction,
18
21
  sendAction,
19
22
  sendHint,
20
23
  } from '../lib/wallet.js';
24
+ import { bigintReplacer } from '../lib/format.js';
21
25
 
22
26
  /** @import {PriceAuthority, PriceDescription, PriceQuote, PriceQuoteValue, PriceQuery,} from '@agoric/zoe/tools/types.js'; */
23
27
 
@@ -82,8 +86,8 @@ export const makeOracleCommand = (logger, io = {}) => {
82
86
 
83
87
  const rpcTools = async () => {
84
88
  // XXX pass fetch to getNetworkConfig() explicitly
85
- const networkConfig = await getNetworkConfig(env);
86
- const utils = await makeRpcUtils({ fetch });
89
+ const networkConfig = await getNetworkConfig({ env: process.env, fetch });
90
+ const utils = await makeVstorageKit({ fetch }, networkConfig);
87
91
 
88
92
  const lookupPriceAggregatorInstance = ([brandIn, brandOut]) => {
89
93
  const name = oracleBrandFeedName(brandIn, brandOut);
@@ -267,10 +271,7 @@ export const makeOracleCommand = (logger, io = {}) => {
267
271
  ) => {
268
272
  const { readLatestHead, networkConfig, lookupPriceAggregatorInstance } =
269
273
  await rpcTools();
270
- const wutil = await makeWalletUtils(
271
- { fetch, execFileSync, delay },
272
- networkConfig,
273
- );
274
+ const wutil = await makeWalletUtils({ fetch, delay }, networkConfig);
274
275
  const unitPrice = scaleDecimals(price);
275
276
 
276
277
  const feedPath = `published.priceFeed.${pair[0]}-${pair[1]}_price_feed`;
@@ -7,21 +7,23 @@ import {
7
7
  makeFollower,
8
8
  makeLeaderFromRpcAddresses,
9
9
  } from '@agoric/casting';
10
+ import { slotToRemotable } from '@agoric/internal/src/storage-test-utils.js';
11
+ import { boardSlottingMarshaller } from '@agoric/vats/tools/board-utils.js';
10
12
  import { Command } from 'commander';
11
13
  import fs from 'fs';
12
14
  import { exit } from 'process';
13
- import { slotToRemotable } from '@agoric/internal/src/storage-test-utils.js';
14
- import { boardSlottingMarshaller } from '@agoric/vats/tools/board-utils.js';
15
15
  import { makeLeaderOptions } from '../lib/casting.js';
16
16
  import {
17
17
  execSwingsetTransaction,
18
18
  normalizeAddressWithOptions,
19
19
  } from '../lib/chain.js';
20
- import { networkConfig } from '../lib/rpc.js';
20
+ import { getNetworkConfig } from '../lib/network-config.js';
21
21
 
22
22
  // tight for perf testing but less than this tends to hang.
23
23
  const SLEEP_SECONDS = 0.1;
24
24
 
25
+ const networkConfig = await getNetworkConfig({ env: process.env, fetch });
26
+
25
27
  /**
26
28
  * @param {import('anylogger').Logger} logger
27
29
  */
@@ -1,11 +1,14 @@
1
1
  // @ts-check
2
2
  /* eslint-disable func-names */
3
3
  /* eslint-env node */
4
- import { Command } from 'commander';
4
+ import { makeVstorageKit, storageHelper } from '@agoric/client-utils';
5
5
  import { Offers } from '@agoric/inter-protocol/src/clientSupport.js';
6
- import { asPercent } from '../lib/format.js';
7
- import { makeRpcUtils, storageHelper } from '../lib/rpc.js';
6
+ import { Command } from 'commander';
7
+ import { getNetworkConfig } from '../lib/network-config.js';
8
8
  import { outputExecuteOfferAction } from '../lib/wallet.js';
9
+ import { asPercent } from '../lib/format.js';
10
+
11
+ const networkConfig = await getNetworkConfig({ env: process.env, fetch });
9
12
 
10
13
  // Adapted from https://gist.github.com/dckc/8b5b2f16395cb4d7f2ff340e0bc6b610#file-psm-tool
11
14
 
@@ -60,7 +63,7 @@ export const makePsmCommand = logger => {
60
63
  );
61
64
 
62
65
  const rpcTools = async () => {
63
- const utils = await makeRpcUtils({ fetch });
66
+ const utils = await makeVstorageKit({ fetch }, networkConfig);
64
67
 
65
68
  const lookupPsmInstance = ([minted, anchor]) => {
66
69
  const name = `psm-${minted}-${anchor}`;
@@ -1,11 +1,14 @@
1
1
  // @ts-check
2
2
  /* eslint-disable func-names */
3
3
  /* eslint-env node */
4
+ import { makeVstorageKit } from '@agoric/client-utils';
4
5
  import { Offers } from '@agoric/inter-protocol/src/clientSupport.js';
5
6
  import { Command } from 'commander';
6
- import { makeRpcUtils } from '../lib/rpc.js';
7
+ import { getNetworkConfig } from '../lib/network-config.js';
7
8
  import { outputActionAndHint } from '../lib/wallet.js';
8
9
 
10
+ const networkConfig = await getNetworkConfig({ env: process.env, fetch });
11
+
9
12
  /**
10
13
  * @param {import('anylogger').Logger} _logger
11
14
  * @param {*} io
@@ -29,7 +32,7 @@ export const makeReserveCommand = (_logger, io = {}) => {
29
32
  * }} opts
30
33
  */
31
34
  async ({ collateralBrand, ...opts }) => {
32
- const { agoricNames } = await makeRpcUtils({ fetch });
35
+ const { agoricNames } = await makeVstorageKit({ fetch }, networkConfig);
33
36
 
34
37
  const offer = Offers.reserve.AddCollateral(agoricNames, {
35
38
  collateralBrandKey: collateralBrand,
@@ -63,7 +66,7 @@ export const makeReserveCommand = (_logger, io = {}) => {
63
66
  1,
64
67
  )
65
68
  .action(async function (opts) {
66
- const { agoricNames } = await makeRpcUtils({ fetch });
69
+ const { agoricNames } = await makeVstorageKit({ fetch }, networkConfig);
67
70
 
68
71
  const reserveInstance = agoricNames.instance.reserve;
69
72
  assert(reserveInstance, 'missing reserve in names');
@@ -1,11 +1,12 @@
1
1
  // @ts-check
2
2
  /* eslint-env node */
3
+ import { makeWalletUtils } from '@agoric/client-utils';
3
4
  import { Fail } from '@endo/errors';
4
5
  import { CommanderError } from 'commander';
5
6
  import { normalizeAddressWithOptions } from '../lib/chain.js';
7
+ import { getNetworkConfig } from '../lib/network-config.js';
8
+ import { sendAction } from '../lib/wallet.js';
6
9
  import { bigintReplacer } from '../lib/format.js';
7
- import { getNetworkConfig } from '../lib/rpc.js';
8
- import { makeWalletUtils, sendAction } from '../lib/wallet.js';
9
10
 
10
11
  /**
11
12
  * Make commands for testing.
@@ -38,8 +39,8 @@ export const makeTestCommand = (
38
39
  try {
39
40
  // XXX pass fetch to getNetworkConfig() explicitly
40
41
  // await null above makes this await safe
41
- const networkConfig = await getNetworkConfig(env);
42
- return makeWalletUtils({ fetch, execFileSync, delay }, networkConfig);
42
+ const networkConfig = await getNetworkConfig({ env, fetch });
43
+ return makeWalletUtils({ fetch, delay }, networkConfig);
43
44
  } catch (err) {
44
45
  // CommanderError is a class constructor, and so
45
46
  // must be invoked with `new`.
@@ -1,14 +1,17 @@
1
1
  // @ts-check
2
2
  /* eslint-disable func-names */
3
3
  /* eslint-env node */
4
- import { Command } from 'commander';
4
+ import { makeVstorageKit } from '@agoric/client-utils';
5
5
  import {
6
6
  lookupOfferIdForVault,
7
7
  Offers,
8
8
  } from '@agoric/inter-protocol/src/clientSupport.js';
9
+ import { Command } from 'commander';
9
10
  import { normalizeAddressWithOptions } from '../lib/chain.js';
10
- import { makeRpcUtils } from '../lib/rpc.js';
11
11
  import { getCurrent, outputExecuteOfferAction } from '../lib/wallet.js';
12
+ import { getNetworkConfig } from '../lib/network-config.js';
13
+
14
+ const networkConfig = await getNetworkConfig({ env: process.env, fetch });
12
15
 
13
16
  /**
14
17
  * @param {import('anylogger').Logger} logger
@@ -36,7 +39,10 @@ export const makeVaultsCommand = logger => {
36
39
  normalizeAddress,
37
40
  )
38
41
  .action(async function (opts) {
39
- const { readLatestHead } = await makeRpcUtils({ fetch });
42
+ const { readLatestHead } = await makeVstorageKit(
43
+ { fetch },
44
+ networkConfig,
45
+ );
40
46
 
41
47
  const current = await getCurrent(opts.from, {
42
48
  readLatestHead,
@@ -61,7 +67,7 @@ export const makeVaultsCommand = logger => {
61
67
  .option('--collateralBrand <string>', 'Collateral brand key', 'ATOM')
62
68
  .action(async function (opts) {
63
69
  logger.warn('running with options', opts);
64
- const { agoricNames } = await makeRpcUtils({ fetch });
70
+ const { agoricNames } = await makeVstorageKit({ fetch }, networkConfig);
65
71
 
66
72
  const offer = Offers.vaults.OpenVault(agoricNames, {
67
73
  giveCollateral: opts.giveCollateral,
@@ -96,7 +102,10 @@ export const makeVaultsCommand = logger => {
96
102
  .requiredOption('--vaultId <string>', 'Key of vault (e.g. vault1)')
97
103
  .action(async function (opts) {
98
104
  logger.warn('running with options', opts);
99
- const { agoricNames, readLatestHead } = await makeRpcUtils({ fetch });
105
+ const { agoricNames, readLatestHead } = await makeVstorageKit(
106
+ { fetch },
107
+ networkConfig,
108
+ );
100
109
 
101
110
  const previousOfferId = await lookupOfferIdForVault(
102
111
  opts.vaultId,
@@ -137,7 +146,10 @@ export const makeVaultsCommand = logger => {
137
146
  )
138
147
  .action(async function (opts) {
139
148
  logger.warn('running with options', opts);
140
- const { agoricNames, readLatestHead } = await makeRpcUtils({ fetch });
149
+ const { agoricNames, readLatestHead } = await makeVstorageKit(
150
+ { fetch },
151
+ networkConfig,
152
+ );
141
153
 
142
154
  const previousOfferId = await lookupOfferIdForVault(
143
155
  opts.vaultId,
@@ -8,11 +8,10 @@ import {
8
8
  makeLeader,
9
9
  makeLeaderFromRpcAddresses,
10
10
  } from '@agoric/casting';
11
+ import { makeVstorageKit } from '@agoric/client-utils';
12
+ import { execFileSync } from 'child_process';
11
13
  import fs from 'fs';
12
14
  import util from 'util';
13
- import { execFileSync } from 'child_process';
14
- import { fmtRecordOfLines, summarize } from '../lib/format.js';
15
- import { makeRpcUtils, networkConfig } from '../lib/rpc.js';
16
15
 
17
16
  import { makeLeaderOptions } from '../lib/casting.js';
18
17
  import {
@@ -20,7 +19,11 @@ import {
20
19
  fetchSwingsetParams,
21
20
  normalizeAddressWithOptions,
22
21
  } from '../lib/chain.js';
22
+ import { getNetworkConfig } from '../lib/network-config.js';
23
23
  import { coalesceWalletState, getCurrent } from '../lib/wallet.js';
24
+ import { summarize, fmtRecordOfLines } from '../lib/format.js';
25
+
26
+ const networkConfig = await getNetworkConfig({ env: process.env, fetch });
24
27
 
25
28
  const SLEEP_SECONDS = 3;
26
29
 
@@ -102,7 +105,7 @@ export const makeWalletCommand = async command => {
102
105
  .action(async function (opts) {
103
106
  const offerStr = fs.readFileSync(opts.file).toString();
104
107
 
105
- const { unserializer } = await makeRpcUtils({ fetch });
108
+ const { unserializer } = await makeVstorageKit({ fetch }, networkConfig);
106
109
 
107
110
  const offerObj = unserializer.fromCapData(JSON.parse(offerStr));
108
111
  console.log(offerObj);
@@ -117,7 +120,7 @@ export const makeWalletCommand = async command => {
117
120
  .action(async function (opts) {
118
121
  const offerStr = fs.readFileSync(opts.offer).toString();
119
122
 
120
- const { unserializer } = await makeRpcUtils({ fetch });
123
+ const { unserializer } = await makeVstorageKit({ fetch }, networkConfig);
121
124
 
122
125
  const offerObj = unserializer.fromCapData(JSON.parse(offerStr));
123
126
  console.log(offerObj.offer.id);
@@ -155,7 +158,7 @@ export const makeWalletCommand = async command => {
155
158
  .command('list')
156
159
  .description('list all wallets in vstorage')
157
160
  .action(async function () {
158
- const { vstorage } = await makeRpcUtils({ fetch });
161
+ const { vstorage } = await makeVstorageKit({ fetch }, networkConfig);
159
162
  const wallets = await vstorage.keys('published.wallet');
160
163
  process.stdout.write(wallets.join('\n'));
161
164
  });
@@ -169,16 +172,19 @@ export const makeWalletCommand = async command => {
169
172
  normalizeAddress,
170
173
  )
171
174
  .action(async function (opts) {
172
- const { agoricNames, unserializer, readLatestHead } = await makeRpcUtils({
173
- fetch,
174
- });
175
+ const { agoricNames, unserializer, readLatestHead } =
176
+ await makeVstorageKit(
177
+ {
178
+ fetch,
179
+ },
180
+ networkConfig,
181
+ );
175
182
 
176
183
  const leader = makeLeader(networkConfig.rpcAddrs[0]);
177
184
  const follower = await makeFollower(
178
185
  `:published.wallet.${opts.from}`,
179
186
  leader,
180
187
  {
181
- // @ts-expect-error xxx
182
188
  unserializer,
183
189
  },
184
190
  );
package/src/lib/chain.js CHANGED
@@ -3,6 +3,10 @@
3
3
  import { normalizeBech32 } from '@cosmjs/encoding';
4
4
  import { execFileSync as execFileSyncAmbient } from 'child_process';
5
5
 
6
+ /**
7
+ * @import {MinimalNetworkConfig} from '@agoric/client-utils';
8
+ */
9
+
6
10
  const agdBinary = 'agd';
7
11
 
8
12
  /**
@@ -36,7 +40,7 @@ harden(normalizeAddressWithOptions);
36
40
 
37
41
  /**
38
42
  * @param {ReadonlyArray<string>} swingsetArgs
39
- * @param {import('./rpc.js').MinimalNetworkConfig & {
43
+ * @param {MinimalNetworkConfig & {
40
44
  * from: string,
41
45
  * fees?: string,
42
46
  * dryRun?: boolean,
@@ -94,7 +98,7 @@ harden(execSwingsetTransaction);
94
98
 
95
99
  /**
96
100
  *
97
- * @param {import('./rpc.js').MinimalNetworkConfig} net
101
+ * @param {MinimalNetworkConfig} net
98
102
  */
99
103
  // TODO fetch by HTTP instead of shelling out https://github.com/Agoric/agoric-sdk/issues/9200
100
104
  export const fetchSwingsetParams = net => {
@@ -114,7 +118,7 @@ export const fetchSwingsetParams = net => {
114
118
  harden(fetchSwingsetParams);
115
119
 
116
120
  /**
117
- * @param {import('./rpc.js').MinimalNetworkConfig & {
121
+ * @param {MinimalNetworkConfig & {
118
122
  * execFileSync: typeof import('child_process').execFileSync,
119
123
  * delay: (ms: number) => Promise<void>,
120
124
  * period?: number,
@@ -154,7 +158,7 @@ export const pollBlocks = opts => async lookup => {
154
158
 
155
159
  /**
156
160
  * @param {string} txhash
157
- * @param {import('./rpc.js').MinimalNetworkConfig & {
161
+ * @param {MinimalNetworkConfig & {
158
162
  * execFileSync: typeof import('child_process').execFileSync,
159
163
  * delay: (ms: number) => Promise<void>,
160
164
  * period?: number,
package/src/lib/format.js CHANGED
@@ -1,24 +1,10 @@
1
- // @ts-check
2
-
3
1
  import { Fail, q } from '@endo/errors';
4
2
  import { makeBoardRemote } from '@agoric/vats/tools/board-utils.js';
5
3
 
6
- /** @import {BoardRemote} from '@agoric/vats/tools/board-utils.js' */
7
- /** @import {VBankAssetDetail} from '@agoric/vats/tools/board-utils.js'; */
8
-
9
4
  /**
10
- * Like @endo/nat but coerces
11
- *
12
- * @param {string} str
13
- * @returns {bigint}
5
+ * @import {Amount, Brand} from '@agoric/ertp'
6
+ * @import {AgoricNamesRemotes, BoardRemote, VBankAssetDetail} from '@agoric/vats/tools/board-utils.js';
14
7
  */
15
- export const Natural = str => {
16
- const b = BigInt(str);
17
- if (b < 0) {
18
- throw RangeError(`${b} is negative`);
19
- }
20
- return b;
21
- };
22
8
 
23
9
  /**
24
10
  * JSON.stringify replacer to handle bigint
@@ -117,7 +103,7 @@ export const fmtRecordOfLines = record => {
117
103
  * Summarize the offerStatuses of the state as user-facing informative tuples
118
104
  *
119
105
  * @param {import('@agoric/smart-wallet/src/utils.js').CoalescedWalletState} state
120
- * @param {import('@agoric/vats/tools/board-utils.js').AgoricNamesRemotes} agoricNames
106
+ * @param {AgoricNamesRemotes} agoricNames
121
107
  */
122
108
  export const offerStatusTuples = (state, agoricNames) => {
123
109
  const { offerStatuses } = state;
@@ -174,7 +160,7 @@ export const offerStatusTuples = (state, agoricNames) => {
174
160
  /**
175
161
  * @param {import('@agoric/smart-wallet/src/smartWallet.js').CurrentWalletRecord} current
176
162
  * @param {ReturnType<import('@agoric/smart-wallet/src/utils.js').makeWalletStateCoalescer>['state']} coalesced
177
- * @param {import('@agoric/vats/tools/board-utils.js').AgoricNamesRemotes} agoricNames
163
+ * @param {AgoricNamesRemotes} agoricNames
178
164
  */
179
165
  export const summarize = (current, coalesced, agoricNames) => {
180
166
  return {
@@ -0,0 +1,37 @@
1
+ import { NonNullish } from '@agoric/internal';
2
+
3
+ export const networkConfigUrl = agoricNetSubdomain =>
4
+ `https://${agoricNetSubdomain}.agoric.net/network-config`;
5
+ export const rpcUrl = agoricNetSubdomain =>
6
+ `https://${agoricNetSubdomain}.rpc.agoric.net:443`;
7
+
8
+ /**
9
+ * @param {string} str
10
+ * @param {{ fetch: typeof fetch }} io
11
+ * @returns {Promise<MinimalNetworkConfig>}
12
+ */
13
+ const fromAgoricNet = (str, { fetch }) => {
14
+ const [netName, chainName] = str.split(',');
15
+ if (chainName) {
16
+ return Promise.resolve({ chainName, rpcAddrs: [rpcUrl(netName)] });
17
+ }
18
+ return fetch(networkConfigUrl(netName)).then(res => res.json());
19
+ };
20
+
21
+ /**
22
+ * @param {{ env: typeof process.env, fetch: typeof fetch }} io
23
+ * @returns {Promise<MinimalNetworkConfig>}
24
+ */
25
+ export const getNetworkConfig = async ({ env, fetch }) => {
26
+ if (!('AGORIC_NET' in env) || env.AGORIC_NET === 'local') {
27
+ return { rpcAddrs: ['http://0.0.0.0:26657'], chainName: 'agoriclocal' };
28
+ }
29
+
30
+ return fromAgoricNet(NonNullish(env.AGORIC_NET), { fetch }).catch(err => {
31
+ throw Error(
32
+ `cannot get network config (${env.AGORIC_NET || 'local'}): ${
33
+ err.message
34
+ }`,
35
+ );
36
+ });
37
+ };
package/src/lib/wallet.js CHANGED
@@ -1,14 +1,17 @@
1
1
  // @ts-check
2
2
  /* eslint-env node */
3
3
 
4
- import { Fail } from '@endo/errors';
5
4
  import { iterateReverse } from '@agoric/casting';
5
+ import { boardSlottingMarshaller } from '@agoric/client-utils';
6
6
  import { makeWalletStateCoalescer } from '@agoric/smart-wallet/src/utils.js';
7
- import { execSwingsetTransaction, pollBlocks, pollTx } from './chain.js';
8
- import { boardSlottingMarshaller, makeRpcUtils } from './rpc.js';
7
+ import { Fail } from '@endo/errors';
8
+ import { execSwingsetTransaction, pollTx } from './chain.js';
9
9
 
10
- /** @import {CurrentWalletRecord} from '@agoric/smart-wallet/src/smartWallet.js' */
11
- /** @import {AgoricNamesRemotes} from '@agoric/vats/tools/board-utils.js' */
10
+ /**
11
+ * @import {CurrentWalletRecord} from '@agoric/smart-wallet/src/smartWallet.js';
12
+ * @import {AgoricNamesRemotes} from '@agoric/vats/tools/board-utils.js';
13
+ * @import {MinimalNetworkConfig, WalletUtils} from '@agoric/client-utils';
14
+ */
12
15
 
13
16
  const marshaller = boardSlottingMarshaller();
14
17
 
@@ -22,7 +25,7 @@ const emptyCurrentRecord = {
22
25
 
23
26
  /**
24
27
  * @param {string} addr
25
- * @param {Pick<import('./rpc.js').RpcUtils, 'readLatestHead'>} io
28
+ * @param {Pick<WalletUtils, 'readLatestHead'>} io
26
29
  * @returns {Promise<import('@agoric/smart-wallet/src/smartWallet.js').CurrentWalletRecord>}
27
30
  */
28
31
  export const getCurrent = async (addr, { readLatestHead }) => {
@@ -57,7 +60,7 @@ export const getCurrent = async (addr, { readLatestHead }) => {
57
60
 
58
61
  /**
59
62
  * @param {string} addr
60
- * @param {Pick<import('./rpc.js').RpcUtils, 'readLatestHead'>} io
63
+ * @param {Pick<WalletUtils, 'readLatestHead'>} io
61
64
  * @returns {Promise<import('@agoric/smart-wallet/src/smartWallet.js').UpdateRecord>}
62
65
  */
63
66
  export const getLastUpdate = (addr, { readLatestHead }) => {
@@ -142,7 +145,7 @@ export const coalesceWalletState = async (follower, invitationBrand) => {
142
145
  *
143
146
  * @throws { Error & { code: number } } if transaction fails
144
147
  * @param {import('@agoric/smart-wallet/src/smartWallet.js').BridgeAction} bridgeAction
145
- * @param {import('./rpc.js').MinimalNetworkConfig & {
148
+ * @param {MinimalNetworkConfig & {
146
149
  * from: string,
147
150
  * fees?: string,
148
151
  * verbose?: boolean,
@@ -211,76 +214,3 @@ export const findContinuingIds = (current, agoricNames) => {
211
214
  }
212
215
  return found;
213
216
  };
214
-
215
- export const makeWalletUtils = async (
216
- { fetch, execFileSync, delay },
217
- networkConfig,
218
- ) => {
219
- const { agoricNames, fromBoard, readLatestHead, vstorage } =
220
- await makeRpcUtils({ fetch }, networkConfig);
221
- /**
222
- * @param {string} from
223
- * @param {number|string} [minHeight]
224
- */
225
- const storedWalletState = async (from, minHeight = undefined) => {
226
- const m = boardSlottingMarshaller(fromBoard.convertSlotToVal);
227
-
228
- const history = await vstorage.readFully(
229
- `published.wallet.${from}`,
230
- minHeight,
231
- );
232
-
233
- /** @type {{ Invitation: Brand<'set'> }} */
234
- // @ts-expect-error XXX how to narrow AssetKind to set?
235
- const { Invitation } = agoricNames.brand;
236
- const coalescer = makeWalletStateCoalescer(Invitation);
237
- // update with oldest first
238
- for (const txt of history.reverse()) {
239
- const { body, slots } = JSON.parse(txt);
240
- const record = m.fromCapData({ body, slots });
241
- coalescer.update(record);
242
- }
243
- const coalesced = coalescer.state;
244
- harden(coalesced);
245
- return coalesced;
246
- };
247
-
248
- /**
249
- * Get OfferStatus by id, polling until available.
250
- *
251
- * @param {string} from
252
- * @param {string|number} id
253
- * @param {number|string} minHeight
254
- * @param {boolean} [untilNumWantsSatisfied]
255
- */
256
- const pollOffer = async (
257
- from,
258
- id,
259
- minHeight,
260
- untilNumWantsSatisfied = false,
261
- ) => {
262
- const lookup = async () => {
263
- const { offerStatuses } = await storedWalletState(from, minHeight);
264
- const offerStatus = [...offerStatuses.values()].find(s => s.id === id);
265
- if (!offerStatus) throw Error('retry');
266
- harden(offerStatus);
267
- if (untilNumWantsSatisfied && !('numWantsSatisfied' in offerStatus)) {
268
- throw Error('retry (no numWantsSatisfied yet)');
269
- }
270
- return offerStatus;
271
- };
272
- const retryMessage = 'offer not in wallet at block';
273
- const opts = { ...networkConfig, execFileSync, delay, retryMessage };
274
- return pollBlocks(opts)(lookup);
275
- };
276
-
277
- return {
278
- networkConfig,
279
- agoricNames,
280
- fromBoard,
281
- vstorage,
282
- readLatestHead,
283
- storedWalletState,
284
- pollOffer,
285
- };
286
- };
@@ -9,6 +9,7 @@ export default [
9
9
  "@agoric/builders",
10
10
  "@agoric/cache",
11
11
  "@agoric/casting",
12
+ "@agoric/client-utils",
12
13
  "@agoric/cosmic-proto",
13
14
  "@agoric/cosmic-swingset",
14
15
  "@agoric/cosmos",
package/src/lib/rpc.js DELETED
@@ -1,285 +0,0 @@
1
- // @ts-check
2
- /* eslint-env node */
3
-
4
- import { NonNullish } from '@agoric/internal';
5
- import {
6
- boardSlottingMarshaller,
7
- makeBoardRemote,
8
- } from '@agoric/vats/tools/board-utils.js';
9
-
10
- export { boardSlottingMarshaller };
11
-
12
- export const networkConfigUrl = agoricNetSubdomain =>
13
- `https://${agoricNetSubdomain}.agoric.net/network-config`;
14
- export const rpcUrl = agoricNetSubdomain =>
15
- `https://${agoricNetSubdomain}.rpc.agoric.net:443`;
16
-
17
- /**
18
- * @typedef {{ rpcAddrs: string[], chainName: string }} MinimalNetworkConfig
19
- */
20
-
21
- /**
22
- * @param {string} str
23
- * @returns {Promise<MinimalNetworkConfig>}
24
- */
25
- const fromAgoricNet = str => {
26
- const [netName, chainName] = str.split(',');
27
- if (chainName) {
28
- return Promise.resolve({ chainName, rpcAddrs: [rpcUrl(netName)] });
29
- }
30
- return fetch(networkConfigUrl(netName)).then(res => res.json());
31
- };
32
-
33
- /**
34
- * @param {typeof process.env} env
35
- * @returns {Promise<MinimalNetworkConfig>}
36
- */
37
- export const getNetworkConfig = async env => {
38
- if (!('AGORIC_NET' in env) || env.AGORIC_NET === 'local') {
39
- return { rpcAddrs: ['http://0.0.0.0:26657'], chainName: 'agoriclocal' };
40
- }
41
-
42
- return fromAgoricNet(NonNullish(env.AGORIC_NET)).catch(err => {
43
- throw Error(
44
- `cannot get network config (${env.AGORIC_NET || 'local'}): ${
45
- err.message
46
- }`,
47
- );
48
- });
49
- };
50
-
51
- /** @type {MinimalNetworkConfig} */
52
- const networkConfig = await getNetworkConfig(process.env);
53
- export { networkConfig };
54
- // console.warn('networkConfig', networkConfig);
55
-
56
- /**
57
- * @param {object} powers
58
- * @param {typeof window.fetch} powers.fetch
59
- * @param {MinimalNetworkConfig} config
60
- */
61
- export const makeVStorage = (powers, config = networkConfig) => {
62
- /** @param {string} path */
63
- const getJSON = path => {
64
- const url = config.rpcAddrs[0] + path;
65
- // console.warn('fetching', url);
66
- return powers.fetch(url, { keepalive: true }).then(res => res.json());
67
- };
68
- // height=0 is the same as omitting height and implies the highest block
69
- const url = (path = 'published', { kind = 'children', height = 0 } = {}) =>
70
- `/abci_query?path=%22/custom/vstorage/${kind}/${path}%22&height=${height}`;
71
-
72
- const readStorage = (path = 'published', { kind = 'children', height = 0 }) =>
73
- getJSON(url(path, { kind, height }))
74
- .catch(err => {
75
- throw Error(`cannot read ${kind} of ${path}: ${err.message}`);
76
- })
77
- .then(data => {
78
- const {
79
- result: { response },
80
- } = data;
81
- if (response?.code !== 0) {
82
- /** @type {any} */
83
- const err = Error(
84
- `error code ${response?.code} reading ${kind} of ${path}: ${response.log}`,
85
- );
86
- err.code = response?.code;
87
- err.codespace = response?.codespace;
88
- throw err;
89
- }
90
- return data;
91
- });
92
-
93
- return {
94
- url,
95
- decode({ result: { response } }) {
96
- const { code } = response;
97
- if (code !== 0) {
98
- throw response;
99
- }
100
- const { value } = response;
101
- return Buffer.from(value, 'base64').toString();
102
- },
103
- /**
104
- *
105
- * @param {string} path
106
- * @returns {Promise<string>} latest vstorage value at path
107
- */
108
- async readLatest(path = 'published') {
109
- const raw = await readStorage(path, { kind: 'data' });
110
- return this.decode(raw);
111
- },
112
- async keys(path = 'published') {
113
- const raw = await readStorage(path, { kind: 'children' });
114
- return JSON.parse(this.decode(raw)).children;
115
- },
116
- /**
117
- * @param {string} path
118
- * @param {number} [height] default is highest
119
- * @returns {Promise<{blockHeight: number, values: string[]}>}
120
- */
121
- async readAt(path, height = undefined) {
122
- const raw = await readStorage(path, { kind: 'data', height });
123
- const txt = this.decode(raw);
124
- /** @type {{ value: string }} */
125
- const { value } = JSON.parse(txt);
126
- return JSON.parse(value);
127
- },
128
- /**
129
- * Read values going back as far as available
130
- *
131
- * @param {string} path
132
- * @param {number | string} [minHeight]
133
- * @returns {Promise<string[]>}
134
- */
135
- async readFully(path, minHeight = undefined) {
136
- const parts = [];
137
- // undefined the first iteration, to query at the highest
138
- let blockHeight;
139
- await null;
140
- do {
141
- // console.debug('READING', { blockHeight });
142
- let values;
143
- try {
144
- ({ blockHeight, values } = await this.readAt(
145
- path,
146
- blockHeight && Number(blockHeight) - 1,
147
- ));
148
- // console.debug('readAt returned', { blockHeight });
149
- } catch (err) {
150
- if (
151
- // CosmosSDK ErrInvalidRequest with particular message text;
152
- // misrepresentation of pruned data
153
- // TODO replace after incorporating a fix to
154
- // https://github.com/cosmos/cosmos-sdk/issues/19992
155
- err.codespace === 'sdk' &&
156
- err.code === 18 &&
157
- err.message.match(/pruned/)
158
- ) {
159
- // console.error(err);
160
- break;
161
- }
162
- throw err;
163
- }
164
- parts.push(values);
165
- // console.debug('PUSHED', values);
166
- // console.debug('NEW', { blockHeight, minHeight });
167
- if (minHeight && Number(blockHeight) <= Number(minHeight)) break;
168
- } while (blockHeight > 0);
169
- return parts.flat();
170
- },
171
- };
172
- };
173
- /** @typedef {ReturnType<typeof makeVStorage>} VStorage */
174
-
175
- export const makeFromBoard = () => {
176
- const cache = new Map();
177
- const convertSlotToVal = (boardId, iface) => {
178
- if (cache.has(boardId)) {
179
- return cache.get(boardId);
180
- }
181
- const val = makeBoardRemote({ boardId, iface });
182
- cache.set(boardId, val);
183
- return val;
184
- };
185
- return harden({ convertSlotToVal });
186
- };
187
- /** @typedef {ReturnType<typeof makeFromBoard>} IdMap */
188
-
189
- export const storageHelper = {
190
- /** @param { string } txt */
191
- parseCapData: txt => {
192
- assert(typeof txt === 'string', typeof txt);
193
- /** @type {{ value: string }} */
194
- const { value } = JSON.parse(txt);
195
- const specimen = JSON.parse(value);
196
- const { blockHeight, values } = specimen;
197
- assert(values, `empty values in specimen ${value}`);
198
- const capDatas = storageHelper.parseMany(values);
199
- return { blockHeight, capDatas };
200
- },
201
- /**
202
- * @param {string} txt
203
- * @param {IdMap} ctx
204
- */
205
- unserializeTxt: (txt, ctx) => {
206
- const { capDatas } = storageHelper.parseCapData(txt);
207
- return capDatas.map(capData =>
208
- boardSlottingMarshaller(ctx.convertSlotToVal).fromCapData(capData),
209
- );
210
- },
211
- /** @param {string[]} capDataStrings array of stringified capData */
212
- parseMany: capDataStrings => {
213
- assert(capDataStrings && capDataStrings.length);
214
- /** @type {{ body: string, slots: string[] }[]} */
215
- const capDatas = capDataStrings.map(s => JSON.parse(s));
216
- for (const capData of capDatas) {
217
- assert(typeof capData === 'object' && capData !== null);
218
- assert('body' in capData && 'slots' in capData);
219
- assert(typeof capData.body === 'string');
220
- assert(Array.isArray(capData.slots));
221
- }
222
- return capDatas;
223
- },
224
- };
225
- harden(storageHelper);
226
-
227
- /**
228
- * @param {IdMap} ctx
229
- * @param {VStorage} vstorage
230
- * @returns {Promise<import('@agoric/vats/tools/board-utils.js').AgoricNamesRemotes>}
231
- */
232
- export const makeAgoricNames = async (ctx, vstorage) => {
233
- const reverse = {};
234
- const entries = await Promise.all(
235
- ['brand', 'instance', 'vbankAsset'].map(async kind => {
236
- const content = await vstorage.readLatest(
237
- `published.agoricNames.${kind}`,
238
- );
239
- /** @type {Array<[string, import('@agoric/vats/tools/board-utils.js').BoardRemote]>} */
240
- const parts = storageHelper.unserializeTxt(content, ctx).at(-1);
241
- for (const [name, remote] of parts) {
242
- if ('getBoardId' in remote) {
243
- reverse[remote.getBoardId()] = name;
244
- }
245
- }
246
- return [kind, Object.fromEntries(parts)];
247
- }),
248
- );
249
- return { ...Object.fromEntries(entries), reverse };
250
- };
251
-
252
- /**
253
- * @param {{ fetch: typeof window.fetch }} io
254
- * @param {MinimalNetworkConfig} config
255
- */
256
- export const makeRpcUtils = async ({ fetch }, config = networkConfig) => {
257
- await null;
258
- try {
259
- const vstorage = makeVStorage({ fetch }, config);
260
- const fromBoard = makeFromBoard();
261
- const agoricNames = await makeAgoricNames(fromBoard, vstorage);
262
-
263
- const unserializer = boardSlottingMarshaller(fromBoard.convertSlotToVal);
264
-
265
- /** @type {(txt: string) => unknown} */
266
- const unserializeHead = txt =>
267
- storageHelper.unserializeTxt(txt, fromBoard).at(-1);
268
-
269
- /** @type {(path: string) => Promise<unknown>} */
270
- const readLatestHead = path =>
271
- vstorage.readLatest(path).then(unserializeHead);
272
-
273
- return {
274
- agoricNames,
275
- fromBoard,
276
- readLatestHead,
277
- unserializeHead,
278
- unserializer,
279
- vstorage,
280
- };
281
- } catch (err) {
282
- throw Error(`RPC failure (${config.rpcAddrs}): ${err.message}`);
283
- }
284
- };
285
- /** @typedef {Awaited<ReturnType<typeof makeRpcUtils>>} RpcUtils */