From 5108ab1bf9d2d290535ee4b6588ee0e86d5b11c6 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Mon, 4 Nov 2024 15:15:49 -0800 Subject: [PATCH 01/19] lint: eslint-env node --- packages/cosmic-proto/scripts/codegen.cjs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/cosmic-proto/scripts/codegen.cjs b/packages/cosmic-proto/scripts/codegen.cjs index 62d68c7451e..0de1c063495 100644 --- a/packages/cosmic-proto/scripts/codegen.cjs +++ b/packages/cosmic-proto/scripts/codegen.cjs @@ -1,3 +1,5 @@ +#!/usr/bin/env node +/* eslint-env node */ const { exec, spawnSync } = require('child_process'); const path = require('path'); const process = require('process'); @@ -28,7 +30,6 @@ function fixTypeImport(directory) { } if (stderr) { console.error(`Standard error: ${stderr}`); - return; } }); } From e73afcb2343e885d81270ccda5c6f20f7a6c0ac4 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Tue, 5 Nov 2024 11:55:44 -0800 Subject: [PATCH 02/19] build: smart-wallet doesn't need casting --- packages/smart-wallet/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/smart-wallet/package.json b/packages/smart-wallet/package.json index bd9cd503a8b..dd5f9378041 100644 --- a/packages/smart-wallet/package.json +++ b/packages/smart-wallet/package.json @@ -17,6 +17,7 @@ "lint:eslint": "eslint ." }, "devDependencies": { + "@agoric/casting": "^0.4.2", "@agoric/cosmic-proto": "^0.4.0", "@agoric/swingset-vat": "^0.32.2", "@endo/bundle-source": "^3.4.2", @@ -27,7 +28,6 @@ }, "dependencies": { "@endo/errors": "^1.2.7", - "@agoric/casting": "^0.4.2", "@agoric/ertp": "^0.16.2", "@agoric/internal": "^0.3.2", "@agoric/notifier": "^0.6.2", From 769de1fd5edd6d6986d271e100eae7c2d0d2c294 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Tue, 5 Nov 2024 05:53:11 -0800 Subject: [PATCH 03/19] chore(types): less ambient --- packages/agoric-cli/src/lib/format.js | 6 ++++-- packages/smart-wallet/src/types.ts | 5 +++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/agoric-cli/src/lib/format.js b/packages/agoric-cli/src/lib/format.js index 78227bcd615..d3747d24985 100644 --- a/packages/agoric-cli/src/lib/format.js +++ b/packages/agoric-cli/src/lib/format.js @@ -3,8 +3,10 @@ import { Fail, q } from '@endo/errors'; import { makeBoardRemote } from '@agoric/vats/tools/board-utils.js'; -/** @import {BoardRemote} from '@agoric/vats/tools/board-utils.js' */ -/** @import {VBankAssetDetail} from '@agoric/vats/tools/board-utils.js'; */ +/** + * @import {Amount, Brand} from '@agoric/ertp' + * @import {AgoricNamesRemotes, BoardRemote, VBankAssetDetail} from '@agoric/vats/tools/board-utils.js'; + */ /** * Like @endo/nat but coerces diff --git a/packages/smart-wallet/src/types.ts b/packages/smart-wallet/src/types.ts index 94350d9ef53..6100d4b96e8 100644 --- a/packages/smart-wallet/src/types.ts +++ b/packages/smart-wallet/src/types.ts @@ -8,10 +8,15 @@ import type { agoric } from '@agoric/cosmic-proto/agoric/bundle.js'; import type { AgoricNamesRemotes } from '@agoric/vats/tools/board-utils.js'; import type { PublicTopic } from '@agoric/zoe/src/contractSupport/topics.js'; +import type { Payment } from '@agoric/ertp'; import type { OfferSpec } from './offers.js'; declare const CapDataShape: unique symbol; +// Match the type in Zoe, which can't be imported because it's ambient. +// This omits the parameters that aren't used in this module. +type Invitation = Payment<'set'>; + /** * A petname can either be a plain string or a path for which the first element * is a petname for the origin, and the rest of the elements are a snapshot of From 50af71f2b2c3a1eee9da62dbd87c9cda0521979b Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Mon, 4 Nov 2024 06:58:43 -0800 Subject: [PATCH 04/19] feat: client-utils package --- .github/workflows/test-all-packages.yml | 3 + packages/agoric-cli/package.json | 1 + packages/agoric-cli/src/commands/auction.js | 2 +- packages/agoric-cli/src/commands/gov.js | 2 +- packages/agoric-cli/src/commands/inter.js | 2 +- packages/agoric-cli/src/commands/oracle.js | 6 +- packages/agoric-cli/src/commands/perf.js | 2 +- packages/agoric-cli/src/commands/psm.js | 2 +- packages/agoric-cli/src/commands/reserve.js | 2 +- .../agoric-cli/src/commands/test-upgrade.js | 2 +- packages/agoric-cli/src/commands/vaults.js | 2 +- packages/agoric-cli/src/commands/wallet.js | 2 +- packages/agoric-cli/src/lib/chain.js | 12 ++-- packages/agoric-cli/src/lib/wallet.js | 8 +-- packages/agoric-cli/src/sdk-package-names.js | 1 + packages/agoric-cli/test/inter-cli.test.js | 5 +- packages/client-utils/CHANGELOG.md | 1 + packages/client-utils/README.md | 37 ++++++++++++ packages/client-utils/package.json | 56 +++++++++++++++++++ packages/client-utils/src/main.js | 1 + .../src/lib => client-utils/src}/rpc.js | 4 +- packages/client-utils/tsconfig.json | 9 +++ 22 files changed, 141 insertions(+), 21 deletions(-) create mode 100644 packages/client-utils/CHANGELOG.md create mode 100644 packages/client-utils/README.md create mode 100644 packages/client-utils/package.json create mode 100644 packages/client-utils/src/main.js rename packages/{agoric-cli/src/lib => client-utils/src}/rpc.js (98%) create mode 100644 packages/client-utils/tsconfig.json diff --git a/.github/workflows/test-all-packages.yml b/.github/workflows/test-all-packages.yml index 0c00ee23917..ec0b88ac680 100644 --- a/.github/workflows/test-all-packages.yml +++ b/.github/workflows/test-all-packages.yml @@ -264,6 +264,9 @@ jobs: - name: yarn test (casting) if: (success() || failure()) run: cd packages/casting && yarn ${{ steps.vars.outputs.test }} | $TEST_COLLECT + - name: yarn test (client-utils) + if: (success() || failure()) + run: cd packages/client-utils && yarn ${{ steps.vars.outputs.test }} | $TEST_COLLECT - name: yarn test (create-dapp) run: cd packages/create-dapp && yarn ${{ steps.vars.outputs.test }} | $TEST_COLLECT - name: yarn test (fast-usdc) diff --git a/packages/agoric-cli/package.json b/packages/agoric-cli/package.json index 5c7e8ddbbbc..b28ba182284 100644 --- a/packages/agoric-cli/package.json +++ b/packages/agoric-cli/package.json @@ -40,6 +40,7 @@ "@endo/errors": "^1.2.7", "@agoric/cache": "^0.3.2", "@agoric/casting": "^0.4.2", + "@agoric/client-utils": "^0.1.0", "@agoric/cosmic-proto": "^0.4.0", "@agoric/ertp": "^0.16.2", "@agoric/governance": "^0.10.3", diff --git a/packages/agoric-cli/src/commands/auction.js b/packages/agoric-cli/src/commands/auction.js index e07729a56f3..ce3a0f63f53 100644 --- a/packages/agoric-cli/src/commands/auction.js +++ b/packages/agoric-cli/src/commands/auction.js @@ -2,7 +2,7 @@ import { InvalidArgumentError } from 'commander'; import { Fail } from '@endo/errors'; -import { makeRpcUtils } from '../lib/rpc.js'; +import { makeRpcUtils } from '@agoric/client-utils'; import { outputActionAndHint } from '../lib/wallet.js'; /** diff --git a/packages/agoric-cli/src/commands/gov.js b/packages/agoric-cli/src/commands/gov.js index 8a4b46d49e5..c2a64aa8fe6 100644 --- a/packages/agoric-cli/src/commands/gov.js +++ b/packages/agoric-cli/src/commands/gov.js @@ -4,7 +4,7 @@ import { execFileSync as execFileSyncAmbient } from 'child_process'; import { Command, CommanderError } from 'commander'; import { normalizeAddressWithOptions, pollBlocks } from '../lib/chain.js'; -import { getNetworkConfig, makeRpcUtils } from '../lib/rpc.js'; +import { getNetworkConfig, makeRpcUtils } from '@agoric/client-utils'; import { findContinuingIds, getCurrent, diff --git a/packages/agoric-cli/src/commands/inter.js b/packages/agoric-cli/src/commands/inter.js index 702b2ae0f48..e0b108c0610 100644 --- a/packages/agoric-cli/src/commands/inter.js +++ b/packages/agoric-cli/src/commands/inter.js @@ -17,7 +17,7 @@ import { bigintReplacer, makeAmountFormatter, } from '../lib/format.js'; -import { getNetworkConfig } from '../lib/rpc.js'; +import { getNetworkConfig } from '@agoric/client-utils'; import { getCurrent, makeWalletUtils, diff --git a/packages/agoric-cli/src/commands/oracle.js b/packages/agoric-cli/src/commands/oracle.js index 520de3ba710..df58ca232a4 100644 --- a/packages/agoric-cli/src/commands/oracle.js +++ b/packages/agoric-cli/src/commands/oracle.js @@ -10,7 +10,11 @@ import { Command } from 'commander'; import { inspect } from 'util'; import { normalizeAddressWithOptions } from '../lib/chain.js'; import { bigintReplacer } from '../lib/format.js'; -import { getNetworkConfig, makeRpcUtils, storageHelper } from '../lib/rpc.js'; +import { + getNetworkConfig, + makeRpcUtils, + storageHelper, +} from '@agoric/client-utils'; import { getCurrent, makeWalletUtils, diff --git a/packages/agoric-cli/src/commands/perf.js b/packages/agoric-cli/src/commands/perf.js index 199101a6fa4..a655ef58f88 100644 --- a/packages/agoric-cli/src/commands/perf.js +++ b/packages/agoric-cli/src/commands/perf.js @@ -17,7 +17,7 @@ import { execSwingsetTransaction, normalizeAddressWithOptions, } from '../lib/chain.js'; -import { networkConfig } from '../lib/rpc.js'; +import { networkConfig } from '@agoric/client-utils'; // tight for perf testing but less than this tends to hang. const SLEEP_SECONDS = 0.1; diff --git a/packages/agoric-cli/src/commands/psm.js b/packages/agoric-cli/src/commands/psm.js index 8b2af277d58..e9cd0e64c6e 100644 --- a/packages/agoric-cli/src/commands/psm.js +++ b/packages/agoric-cli/src/commands/psm.js @@ -4,7 +4,7 @@ import { Command } from 'commander'; import { Offers } from '@agoric/inter-protocol/src/clientSupport.js'; import { asPercent } from '../lib/format.js'; -import { makeRpcUtils, storageHelper } from '../lib/rpc.js'; +import { makeRpcUtils, storageHelper } from '@agoric/client-utils'; import { outputExecuteOfferAction } from '../lib/wallet.js'; // Adapted from https://gist.github.com/dckc/8b5b2f16395cb4d7f2ff340e0bc6b610#file-psm-tool diff --git a/packages/agoric-cli/src/commands/reserve.js b/packages/agoric-cli/src/commands/reserve.js index 4e55b921761..396dffb4af5 100644 --- a/packages/agoric-cli/src/commands/reserve.js +++ b/packages/agoric-cli/src/commands/reserve.js @@ -3,7 +3,7 @@ /* eslint-env node */ import { Offers } from '@agoric/inter-protocol/src/clientSupport.js'; import { Command } from 'commander'; -import { makeRpcUtils } from '../lib/rpc.js'; +import { makeRpcUtils } from '@agoric/client-utils'; import { outputActionAndHint } from '../lib/wallet.js'; /** diff --git a/packages/agoric-cli/src/commands/test-upgrade.js b/packages/agoric-cli/src/commands/test-upgrade.js index d9d7c977bd6..3eb1b1aaef0 100644 --- a/packages/agoric-cli/src/commands/test-upgrade.js +++ b/packages/agoric-cli/src/commands/test-upgrade.js @@ -4,7 +4,7 @@ import { Fail } from '@endo/errors'; import { CommanderError } from 'commander'; import { normalizeAddressWithOptions } from '../lib/chain.js'; import { bigintReplacer } from '../lib/format.js'; -import { getNetworkConfig } from '../lib/rpc.js'; +import { getNetworkConfig } from '@agoric/client-utils'; import { makeWalletUtils, sendAction } from '../lib/wallet.js'; /** diff --git a/packages/agoric-cli/src/commands/vaults.js b/packages/agoric-cli/src/commands/vaults.js index 523b6170069..55b6f70cfcb 100644 --- a/packages/agoric-cli/src/commands/vaults.js +++ b/packages/agoric-cli/src/commands/vaults.js @@ -7,7 +7,7 @@ import { Offers, } from '@agoric/inter-protocol/src/clientSupport.js'; import { normalizeAddressWithOptions } from '../lib/chain.js'; -import { makeRpcUtils } from '../lib/rpc.js'; +import { makeRpcUtils } from '@agoric/client-utils'; import { getCurrent, outputExecuteOfferAction } from '../lib/wallet.js'; /** diff --git a/packages/agoric-cli/src/commands/wallet.js b/packages/agoric-cli/src/commands/wallet.js index 961b480ee3b..286bec42281 100644 --- a/packages/agoric-cli/src/commands/wallet.js +++ b/packages/agoric-cli/src/commands/wallet.js @@ -12,7 +12,7 @@ import fs from 'fs'; import util from 'util'; import { execFileSync } from 'child_process'; import { fmtRecordOfLines, summarize } from '../lib/format.js'; -import { makeRpcUtils, networkConfig } from '../lib/rpc.js'; +import { makeRpcUtils, networkConfig } from '@agoric/client-utils'; import { makeLeaderOptions } from '../lib/casting.js'; import { diff --git a/packages/agoric-cli/src/lib/chain.js b/packages/agoric-cli/src/lib/chain.js index 282650c31bf..ac8ecd8b0af 100644 --- a/packages/agoric-cli/src/lib/chain.js +++ b/packages/agoric-cli/src/lib/chain.js @@ -3,6 +3,10 @@ import { normalizeBech32 } from '@cosmjs/encoding'; import { execFileSync as execFileSyncAmbient } from 'child_process'; +/** + * @import {MinimalNetworkConfig} from '@agoric/client-utils'; + */ + const agdBinary = 'agd'; /** @@ -36,7 +40,7 @@ harden(normalizeAddressWithOptions); /** * @param {ReadonlyArray} swingsetArgs - * @param {import('./rpc.js').MinimalNetworkConfig & { + * @param {MinimalNetworkConfig & { * from: string, * fees?: string, * dryRun?: boolean, @@ -94,7 +98,7 @@ harden(execSwingsetTransaction); /** * - * @param {import('./rpc.js').MinimalNetworkConfig} net + * @param {MinimalNetworkConfig} net */ // TODO fetch by HTTP instead of shelling out https://github.com/Agoric/agoric-sdk/issues/9200 export const fetchSwingsetParams = net => { @@ -114,7 +118,7 @@ export const fetchSwingsetParams = net => { harden(fetchSwingsetParams); /** - * @param {import('./rpc.js').MinimalNetworkConfig & { + * @param {MinimalNetworkConfig & { * execFileSync: typeof import('child_process').execFileSync, * delay: (ms: number) => Promise, * period?: number, @@ -154,7 +158,7 @@ export const pollBlocks = opts => async lookup => { /** * @param {string} txhash - * @param {import('./rpc.js').MinimalNetworkConfig & { + * @param {MinimalNetworkConfig & { * execFileSync: typeof import('child_process').execFileSync, * delay: (ms: number) => Promise, * period?: number, diff --git a/packages/agoric-cli/src/lib/wallet.js b/packages/agoric-cli/src/lib/wallet.js index abb2f417b33..0980a4cedf5 100644 --- a/packages/agoric-cli/src/lib/wallet.js +++ b/packages/agoric-cli/src/lib/wallet.js @@ -5,7 +5,7 @@ import { Fail } from '@endo/errors'; import { iterateReverse } from '@agoric/casting'; import { makeWalletStateCoalescer } from '@agoric/smart-wallet/src/utils.js'; import { execSwingsetTransaction, pollBlocks, pollTx } from './chain.js'; -import { boardSlottingMarshaller, makeRpcUtils } from './rpc.js'; +import { boardSlottingMarshaller, makeRpcUtils } from '@agoric/client-utils'; /** @import {CurrentWalletRecord} from '@agoric/smart-wallet/src/smartWallet.js' */ /** @import {AgoricNamesRemotes} from '@agoric/vats/tools/board-utils.js' */ @@ -22,7 +22,7 @@ const emptyCurrentRecord = { /** * @param {string} addr - * @param {Pick} io + * @param {Pick} io * @returns {Promise} */ export const getCurrent = async (addr, { readLatestHead }) => { @@ -57,7 +57,7 @@ export const getCurrent = async (addr, { readLatestHead }) => { /** * @param {string} addr - * @param {Pick} io + * @param {Pick} io * @returns {Promise} */ export const getLastUpdate = (addr, { readLatestHead }) => { @@ -142,7 +142,7 @@ export const coalesceWalletState = async (follower, invitationBrand) => { * * @throws { Error & { code: number } } if transaction fails * @param {import('@agoric/smart-wallet/src/smartWallet.js').BridgeAction} bridgeAction - * @param {import('./rpc.js').MinimalNetworkConfig & { + * @param {import('../../../client-utils/src/rpc.js').MinimalNetworkConfig & { * from: string, * fees?: string, * verbose?: boolean, diff --git a/packages/agoric-cli/src/sdk-package-names.js b/packages/agoric-cli/src/sdk-package-names.js index 483c22208ad..70e5eec1242 100644 --- a/packages/agoric-cli/src/sdk-package-names.js +++ b/packages/agoric-cli/src/sdk-package-names.js @@ -9,6 +9,7 @@ export default [ "@agoric/builders", "@agoric/cache", "@agoric/casting", + "@agoric/client-utils", "@agoric/cosmic-proto", "@agoric/cosmic-swingset", "@agoric/cosmos", diff --git a/packages/agoric-cli/test/inter-cli.test.js b/packages/agoric-cli/test/inter-cli.test.js index 2a8023c15f0..4d2ffa2c752 100644 --- a/packages/agoric-cli/test/inter-cli.test.js +++ b/packages/agoric-cli/test/inter-cli.test.js @@ -6,7 +6,10 @@ import { createCommand, CommanderError } from 'commander'; import { Far } from '@endo/far'; import { makeParseAmount } from '@agoric/inter-protocol/src/clientSupport.js'; -import { boardSlottingMarshaller, makeFromBoard } from '../src/lib/rpc.js'; +import { + boardSlottingMarshaller, + makeFromBoard, +} from '../../client-utils/src/rpc.js'; import { fmtBid, makeInterCommand } from '../src/commands/inter.js'; diff --git a/packages/client-utils/CHANGELOG.md b/packages/client-utils/CHANGELOG.md new file mode 100644 index 00000000000..420e6f23d0e --- /dev/null +++ b/packages/client-utils/CHANGELOG.md @@ -0,0 +1 @@ +# Change Log diff --git a/packages/client-utils/README.md b/packages/client-utils/README.md new file mode 100644 index 00000000000..8311a92d024 --- /dev/null +++ b/packages/client-utils/README.md @@ -0,0 +1,37 @@ +# Client Utils + +Utilities for building clients of an Agoric chain + +## Overview + +The Agoric chain takes mutations through signed messages and reveals state updates through vstorage. This package abstracts the calls to RPC nodes into a [CQRS](https://en.wikipedia.org/wiki/Command%E2%80%93query_separation) interface. The commands are made mostly through an on-chain Smart Wallet and the queries through vstorage. + +## Design + +This package will be used in several kinds of clients: +- CLI (such as the `agoric` command) +- GUI (such as dapps) +- Tests (such as a3p-integration tests) + +As such the modules cannot assume they're running in Node. There are some ambient authorities in common in the above environments (e.g. `setTimeout`) but a further constraint is that these modules will not export ambient authority. Instead they will provide interfaces that are ergonomic for creating empowered objects in the client context. + +## Related packages + +### cli +`agoric` package has a command line UI (CLI) for working with an Agoric chain. It's in this repository at `packages/agoric-cli`. + +### rpc +`@agoric/rpc` is a small library that currently just has utilities for watching vstorage. This package avoids depending on `@agoric/rpc` for now because it: + - is in a separate repository ([ui-kit](https://github.com/Agoric/ui-kit/blob/main/packages/rpc)) so not part of agoric-sdk CI + - depends on `axios` and `vite` which are unnecessary constraints + +Some of the functionality in this package could make sense in that package, but for now it will be ignored. + +### cosmic-proto + +`@agoric/cosmic-proto` is a package that contains the protobuf stubs for the Agoric cosmos-sdk module. At various points it has also held generated RPC clients. Because that package is imported into contracts we've kept those out. They may end up in `@agoric/rpc` eventually. + +### * / clientSupport + +The `clientSupport.js` module of several packages. Some packages export this module with certain helpers that this package may abstract. + diff --git a/packages/client-utils/package.json b/packages/client-utils/package.json new file mode 100644 index 00000000000..c341be722ad --- /dev/null +++ b/packages/client-utils/package.json @@ -0,0 +1,56 @@ +{ + "name": "@agoric/client-utils", + "version": "0.1.0", + "description": "Utilities for building Agoric clients", + "license": "Apache-2.0", + "type": "module", + "main": "src/main.js", + "files": [ + "src" + ], + "scripts": { + "build": "exit 0", + "test": "ava", + "test:c8": "c8 $C8_OPTIONS ava --config=ava-nesm.config.js", + "test:xs": "exit 0", + "lint-fix": "yarn lint:eslint --fix", + "lint": "run-s --continue-on-error lint:*", + "lint:types": "tsc", + "lint:eslint": "eslint ." + }, + "devDependencies": { + "ava": "^5.3.0", + "c8": "^9.1.0", + "ts-blank-space": "^0.4.1" + }, + "dependencies": { + "@agoric/ertp": "^0.16.2", + "@agoric/internal": "^0.3.2", + "@agoric/smart-wallet": "^0.5.3", + "@agoric/vats": "^0.15.1", + "@cosmjs/stargate": "^0.32.3", + "@endo/common": "^1.2.7", + "@endo/errors": "^1.2.7", + "@endo/marshal": "^1.6.1", + "@endo/pass-style": "^1.4.6", + "@endo/patterns": "^1.4.6", + "@endo/promise-kit": "^1.1.7" + }, + "ava": { + "extensions": { + "js": true, + "ts": "module" + }, + "files": [ + "test/**/*.test.*" + ], + "nodeArguments": [ + "--import=ts-blank-space/register", + "--no-warnings" + ], + "require": [ + "@endo/init/debug.js" + ], + "timeout": "20m" + } +} diff --git a/packages/client-utils/src/main.js b/packages/client-utils/src/main.js new file mode 100644 index 00000000000..8b025a9cf0b --- /dev/null +++ b/packages/client-utils/src/main.js @@ -0,0 +1 @@ +export * from './rpc.js'; diff --git a/packages/agoric-cli/src/lib/rpc.js b/packages/client-utils/src/rpc.js similarity index 98% rename from packages/agoric-cli/src/lib/rpc.js rename to packages/client-utils/src/rpc.js index e633aabd93b..f25e68a1fbb 100644 --- a/packages/agoric-cli/src/lib/rpc.js +++ b/packages/client-utils/src/rpc.js @@ -260,7 +260,7 @@ export const makeRpcUtils = async ({ fetch }, config = networkConfig) => { const fromBoard = makeFromBoard(); const agoricNames = await makeAgoricNames(fromBoard, vstorage); - const unserializer = boardSlottingMarshaller(fromBoard.convertSlotToVal); + const marshaller = boardSlottingMarshaller(fromBoard.convertSlotToVal); /** @type {(txt: string) => unknown} */ const unserializeHead = txt => @@ -273,9 +273,9 @@ export const makeRpcUtils = async ({ fetch }, config = networkConfig) => { return { agoricNames, fromBoard, + marshaller, readLatestHead, unserializeHead, - unserializer, vstorage, }; } catch (err) { diff --git a/packages/client-utils/tsconfig.json b/packages/client-utils/tsconfig.json new file mode 100644 index 00000000000..f690da86a72 --- /dev/null +++ b/packages/client-utils/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": {}, + "include": [ + "scripts", + "src", + "test", + ], +} From 3026d9785b587465ae585f540d6dec278a776fdd Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Mon, 4 Nov 2024 15:45:01 -0800 Subject: [PATCH 05/19] build: emit types --- packages/client-utils/package.json | 2 ++ packages/client-utils/tsconfig.build.json | 10 ++++++++++ 2 files changed, 12 insertions(+) create mode 100644 packages/client-utils/tsconfig.build.json diff --git a/packages/client-utils/package.json b/packages/client-utils/package.json index c341be722ad..455c85e6ab6 100644 --- a/packages/client-utils/package.json +++ b/packages/client-utils/package.json @@ -10,6 +10,8 @@ ], "scripts": { "build": "exit 0", + "prepack": "tsc --build tsconfig.build.json", + "postpack": "git clean -f '*.d.ts*' '*.tsbuildinfo'", "test": "ava", "test:c8": "c8 $C8_OPTIONS ava --config=ava-nesm.config.js", "test:xs": "exit 0", diff --git a/packages/client-utils/tsconfig.build.json b/packages/client-utils/tsconfig.build.json new file mode 100644 index 00000000000..548419bdcac --- /dev/null +++ b/packages/client-utils/tsconfig.build.json @@ -0,0 +1,10 @@ +{ + "extends": [ + "./tsconfig.json", + "../../tsconfig-build-options.json" + ], + "exclude": [ + "scripts", + "test", + ] +} From 63c7850ca3524e22ad9470b622b2fc9d28cb834e Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Mon, 4 Nov 2024 07:01:15 -0800 Subject: [PATCH 06/19] refactor: format lib to client-utils --- packages/agoric-cli/src/commands/inter.js | 2 +- packages/agoric-cli/src/commands/oracle.js | 2 +- packages/agoric-cli/src/commands/psm.js | 2 +- packages/agoric-cli/src/commands/test-upgrade.js | 2 +- packages/agoric-cli/src/commands/wallet.js | 2 +- packages/{agoric-cli/src/lib => client-utils/src}/format.js | 4 ++-- packages/client-utils/src/main.js | 1 + 7 files changed, 8 insertions(+), 7 deletions(-) rename packages/{agoric-cli/src/lib => client-utils/src}/format.js (97%) diff --git a/packages/agoric-cli/src/commands/inter.js b/packages/agoric-cli/src/commands/inter.js index e0b108c0610..3125e1740a0 100644 --- a/packages/agoric-cli/src/commands/inter.js +++ b/packages/agoric-cli/src/commands/inter.js @@ -16,7 +16,7 @@ import { asBoardRemote, bigintReplacer, makeAmountFormatter, -} from '../lib/format.js'; +} from '@agoric/client-utils'; import { getNetworkConfig } from '@agoric/client-utils'; import { getCurrent, diff --git a/packages/agoric-cli/src/commands/oracle.js b/packages/agoric-cli/src/commands/oracle.js index df58ca232a4..897eefe1b5b 100644 --- a/packages/agoric-cli/src/commands/oracle.js +++ b/packages/agoric-cli/src/commands/oracle.js @@ -9,7 +9,7 @@ import * as cp from 'child_process'; import { Command } from 'commander'; import { inspect } from 'util'; import { normalizeAddressWithOptions } from '../lib/chain.js'; -import { bigintReplacer } from '../lib/format.js'; +import { bigintReplacer } from '@agoric/client-utils'; import { getNetworkConfig, makeRpcUtils, diff --git a/packages/agoric-cli/src/commands/psm.js b/packages/agoric-cli/src/commands/psm.js index e9cd0e64c6e..af40ad5c847 100644 --- a/packages/agoric-cli/src/commands/psm.js +++ b/packages/agoric-cli/src/commands/psm.js @@ -3,7 +3,7 @@ /* eslint-env node */ import { Command } from 'commander'; import { Offers } from '@agoric/inter-protocol/src/clientSupport.js'; -import { asPercent } from '../lib/format.js'; +import { asPercent } from '@agoric/client-utils'; import { makeRpcUtils, storageHelper } from '@agoric/client-utils'; import { outputExecuteOfferAction } from '../lib/wallet.js'; diff --git a/packages/agoric-cli/src/commands/test-upgrade.js b/packages/agoric-cli/src/commands/test-upgrade.js index 3eb1b1aaef0..1f74e3a99c5 100644 --- a/packages/agoric-cli/src/commands/test-upgrade.js +++ b/packages/agoric-cli/src/commands/test-upgrade.js @@ -3,7 +3,7 @@ import { Fail } from '@endo/errors'; import { CommanderError } from 'commander'; import { normalizeAddressWithOptions } from '../lib/chain.js'; -import { bigintReplacer } from '../lib/format.js'; +import { bigintReplacer } from '@agoric/client-utils'; import { getNetworkConfig } from '@agoric/client-utils'; import { makeWalletUtils, sendAction } from '../lib/wallet.js'; diff --git a/packages/agoric-cli/src/commands/wallet.js b/packages/agoric-cli/src/commands/wallet.js index 286bec42281..f01764d9b6d 100644 --- a/packages/agoric-cli/src/commands/wallet.js +++ b/packages/agoric-cli/src/commands/wallet.js @@ -11,7 +11,7 @@ import { import fs from 'fs'; import util from 'util'; import { execFileSync } from 'child_process'; -import { fmtRecordOfLines, summarize } from '../lib/format.js'; +import { fmtRecordOfLines, summarize } from '@agoric/client-utils'; import { makeRpcUtils, networkConfig } from '@agoric/client-utils'; import { makeLeaderOptions } from '../lib/casting.js'; diff --git a/packages/agoric-cli/src/lib/format.js b/packages/client-utils/src/format.js similarity index 97% rename from packages/agoric-cli/src/lib/format.js rename to packages/client-utils/src/format.js index d3747d24985..a1563005539 100644 --- a/packages/agoric-cli/src/lib/format.js +++ b/packages/client-utils/src/format.js @@ -119,7 +119,7 @@ export const fmtRecordOfLines = record => { * Summarize the offerStatuses of the state as user-facing informative tuples * * @param {import('@agoric/smart-wallet/src/utils.js').CoalescedWalletState} state - * @param {import('@agoric/vats/tools/board-utils.js').AgoricNamesRemotes} agoricNames + * @param {AgoricNamesRemotes} agoricNames */ export const offerStatusTuples = (state, agoricNames) => { const { offerStatuses } = state; @@ -176,7 +176,7 @@ export const offerStatusTuples = (state, agoricNames) => { /** * @param {import('@agoric/smart-wallet/src/smartWallet.js').CurrentWalletRecord} current * @param {ReturnType['state']} coalesced - * @param {import('@agoric/vats/tools/board-utils.js').AgoricNamesRemotes} agoricNames + * @param {AgoricNamesRemotes} agoricNames */ export const summarize = (current, coalesced, agoricNames) => { return { diff --git a/packages/client-utils/src/main.js b/packages/client-utils/src/main.js index 8b025a9cf0b..dca5f6810db 100644 --- a/packages/client-utils/src/main.js +++ b/packages/client-utils/src/main.js @@ -1 +1,2 @@ +export * from './format.js'; export * from './rpc.js'; From 64bf82600881ce7897e852938b59eba425aff527 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Wed, 6 Nov 2024 10:22:13 -0800 Subject: [PATCH 07/19] chore: remove Natural --- packages/client-utils/src/format.js | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/packages/client-utils/src/format.js b/packages/client-utils/src/format.js index a1563005539..2e91d5ddfd5 100644 --- a/packages/client-utils/src/format.js +++ b/packages/client-utils/src/format.js @@ -8,20 +8,6 @@ import { makeBoardRemote } from '@agoric/vats/tools/board-utils.js'; * @import {AgoricNamesRemotes, BoardRemote, VBankAssetDetail} from '@agoric/vats/tools/board-utils.js'; */ -/** - * Like @endo/nat but coerces - * - * @param {string} str - * @returns {bigint} - */ -export const Natural = str => { - const b = BigInt(str); - if (b < 0) { - throw RangeError(`${b} is negative`); - } - return b; -}; - /** * JSON.stringify replacer to handle bigint * From bd97f95df0cf19acd21da3c5789c21d469ce0b41 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Mon, 4 Nov 2024 07:12:38 -0800 Subject: [PATCH 08/19] chore: WalletUtils type --- packages/agoric-cli/src/lib/wallet.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/agoric-cli/src/lib/wallet.js b/packages/agoric-cli/src/lib/wallet.js index 0980a4cedf5..36ac0e01038 100644 --- a/packages/agoric-cli/src/lib/wallet.js +++ b/packages/agoric-cli/src/lib/wallet.js @@ -4,11 +4,14 @@ import { Fail } from '@endo/errors'; import { iterateReverse } from '@agoric/casting'; import { makeWalletStateCoalescer } from '@agoric/smart-wallet/src/utils.js'; -import { execSwingsetTransaction, pollBlocks, pollTx } from './chain.js'; import { boardSlottingMarshaller, makeRpcUtils } from '@agoric/client-utils'; +import { execSwingsetTransaction, pollBlocks, pollTx } from './chain.js'; -/** @import {CurrentWalletRecord} from '@agoric/smart-wallet/src/smartWallet.js' */ -/** @import {AgoricNamesRemotes} from '@agoric/vats/tools/board-utils.js' */ +/** + * @import {CurrentWalletRecord} from '@agoric/smart-wallet/src/smartWallet.js'; + * @import {AgoricNamesRemotes} from '@agoric/vats/tools/board-utils.js'; + * @import {MinimalNetworkConfig, RpcUtils} from '@agoric/client-utils'; + */ const marshaller = boardSlottingMarshaller(); @@ -22,7 +25,7 @@ const emptyCurrentRecord = { /** * @param {string} addr - * @param {Pick} io + * @param {Pick} io * @returns {Promise} */ export const getCurrent = async (addr, { readLatestHead }) => { @@ -57,7 +60,7 @@ export const getCurrent = async (addr, { readLatestHead }) => { /** * @param {string} addr - * @param {Pick} io + * @param {Pick} io * @returns {Promise} */ export const getLastUpdate = (addr, { readLatestHead }) => { @@ -142,7 +145,7 @@ export const coalesceWalletState = async (follower, invitationBrand) => { * * @throws { Error & { code: number } } if transaction fails * @param {import('@agoric/smart-wallet/src/smartWallet.js').BridgeAction} bridgeAction - * @param {import('../../../client-utils/src/rpc.js').MinimalNetworkConfig & { + * @param {import('@agoric/client-utils').MinimalNetworkConfig & { * from: string, * fees?: string, * verbose?: boolean, @@ -284,3 +287,4 @@ export const makeWalletUtils = async ( pollOffer, }; }; +/** @typedef {Awaited>} WalletUtils */ From 858237390ce21f5ed93608ba2418a6e9c3d6c033 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Mon, 4 Nov 2024 07:05:48 -0800 Subject: [PATCH 09/19] lint: cleanup imports --- packages/agoric-cli/src/commands/gov.js | 2 +- packages/agoric-cli/src/commands/inter.js | 15 +++++++-------- packages/agoric-cli/src/commands/oracle.js | 12 ++++++------ packages/agoric-cli/src/commands/perf.js | 2 +- packages/agoric-cli/src/commands/psm.js | 5 ++--- packages/agoric-cli/src/commands/test-upgrade.js | 3 +-- packages/agoric-cli/src/commands/vaults.js | 4 ++-- packages/agoric-cli/src/commands/wallet.js | 10 +++++++--- packages/agoric-cli/src/lib/wallet.js | 4 ++-- packages/agoric-cli/test/inter-cli.test.js | 9 +++------ 10 files changed, 32 insertions(+), 34 deletions(-) diff --git a/packages/agoric-cli/src/commands/gov.js b/packages/agoric-cli/src/commands/gov.js index c2a64aa8fe6..27f15e830e9 100644 --- a/packages/agoric-cli/src/commands/gov.js +++ b/packages/agoric-cli/src/commands/gov.js @@ -1,10 +1,10 @@ // @ts-check /* eslint-disable func-names */ /* global globalThis, process, setTimeout */ +import { getNetworkConfig, makeRpcUtils } from '@agoric/client-utils'; import { execFileSync as execFileSyncAmbient } from 'child_process'; import { Command, CommanderError } from 'commander'; import { normalizeAddressWithOptions, pollBlocks } from '../lib/chain.js'; -import { getNetworkConfig, makeRpcUtils } from '@agoric/client-utils'; import { findContinuingIds, getCurrent, diff --git a/packages/agoric-cli/src/commands/inter.js b/packages/agoric-cli/src/commands/inter.js index 3125e1740a0..9b0f6b65cc3 100644 --- a/packages/agoric-cli/src/commands/inter.js +++ b/packages/agoric-cli/src/commands/inter.js @@ -5,19 +5,18 @@ // @ts-check import { CommanderError, InvalidArgumentError } from 'commander'; -// TODO: should get M from endo https://github.com/Agoric/agoric-sdk/issues/7090 -import { makeOfferSpecShape } from '@agoric/inter-protocol/src/auction/auctionBook.js'; -import { Offers } from '@agoric/inter-protocol/src/clientSupport.js'; -import { objectMap } from '@agoric/internal'; -import { M, matches } from '@agoric/store'; - -import { normalizeAddressWithOptions, pollBlocks } from '../lib/chain.js'; import { asBoardRemote, bigintReplacer, + getNetworkConfig, makeAmountFormatter, } from '@agoric/client-utils'; -import { getNetworkConfig } from '@agoric/client-utils'; +import { makeOfferSpecShape } from '@agoric/inter-protocol/src/auction/auctionBook.js'; +import { Offers } from '@agoric/inter-protocol/src/clientSupport.js'; +import { objectMap } from '@agoric/internal'; +import { M, matches } from '@endo/patterns'; + +import { normalizeAddressWithOptions, pollBlocks } from '../lib/chain.js'; import { getCurrent, makeWalletUtils, diff --git a/packages/agoric-cli/src/commands/oracle.js b/packages/agoric-cli/src/commands/oracle.js index 897eefe1b5b..3873420cc73 100644 --- a/packages/agoric-cli/src/commands/oracle.js +++ b/packages/agoric-cli/src/commands/oracle.js @@ -1,6 +1,12 @@ // @ts-check /* eslint-disable func-names */ /* eslint-env node */ +import { + bigintReplacer, + getNetworkConfig, + makeRpcUtils, + storageHelper, +} from '@agoric/client-utils'; import { Offers } from '@agoric/inter-protocol/src/clientSupport.js'; import { oracleBrandFeedName } from '@agoric/inter-protocol/src/proposals/utils.js'; import { Fail } from '@endo/errors'; @@ -9,12 +15,6 @@ import * as cp from 'child_process'; import { Command } from 'commander'; import { inspect } from 'util'; import { normalizeAddressWithOptions } from '../lib/chain.js'; -import { bigintReplacer } from '@agoric/client-utils'; -import { - getNetworkConfig, - makeRpcUtils, - storageHelper, -} from '@agoric/client-utils'; import { getCurrent, makeWalletUtils, diff --git a/packages/agoric-cli/src/commands/perf.js b/packages/agoric-cli/src/commands/perf.js index a655ef58f88..ab36deee106 100644 --- a/packages/agoric-cli/src/commands/perf.js +++ b/packages/agoric-cli/src/commands/perf.js @@ -10,6 +10,7 @@ import { import { Command } from 'commander'; import fs from 'fs'; import { exit } from 'process'; +import { networkConfig } from '@agoric/client-utils'; import { slotToRemotable } from '@agoric/internal/src/storage-test-utils.js'; import { boardSlottingMarshaller } from '@agoric/vats/tools/board-utils.js'; import { makeLeaderOptions } from '../lib/casting.js'; @@ -17,7 +18,6 @@ import { execSwingsetTransaction, normalizeAddressWithOptions, } from '../lib/chain.js'; -import { networkConfig } from '@agoric/client-utils'; // tight for perf testing but less than this tends to hang. const SLEEP_SECONDS = 0.1; diff --git a/packages/agoric-cli/src/commands/psm.js b/packages/agoric-cli/src/commands/psm.js index af40ad5c847..b2236b58580 100644 --- a/packages/agoric-cli/src/commands/psm.js +++ b/packages/agoric-cli/src/commands/psm.js @@ -1,10 +1,9 @@ // @ts-check /* eslint-disable func-names */ /* eslint-env node */ -import { Command } from 'commander'; +import { asPercent, makeRpcUtils, storageHelper } from '@agoric/client-utils'; import { Offers } from '@agoric/inter-protocol/src/clientSupport.js'; -import { asPercent } from '@agoric/client-utils'; -import { makeRpcUtils, storageHelper } from '@agoric/client-utils'; +import { Command } from 'commander'; import { outputExecuteOfferAction } from '../lib/wallet.js'; // Adapted from https://gist.github.com/dckc/8b5b2f16395cb4d7f2ff340e0bc6b610#file-psm-tool diff --git a/packages/agoric-cli/src/commands/test-upgrade.js b/packages/agoric-cli/src/commands/test-upgrade.js index 1f74e3a99c5..b173e2991cd 100644 --- a/packages/agoric-cli/src/commands/test-upgrade.js +++ b/packages/agoric-cli/src/commands/test-upgrade.js @@ -1,10 +1,9 @@ // @ts-check /* eslint-env node */ +import { bigintReplacer, getNetworkConfig } from '@agoric/client-utils'; import { Fail } from '@endo/errors'; import { CommanderError } from 'commander'; import { normalizeAddressWithOptions } from '../lib/chain.js'; -import { bigintReplacer } from '@agoric/client-utils'; -import { getNetworkConfig } from '@agoric/client-utils'; import { makeWalletUtils, sendAction } from '../lib/wallet.js'; /** diff --git a/packages/agoric-cli/src/commands/vaults.js b/packages/agoric-cli/src/commands/vaults.js index 55b6f70cfcb..4953351aa45 100644 --- a/packages/agoric-cli/src/commands/vaults.js +++ b/packages/agoric-cli/src/commands/vaults.js @@ -1,13 +1,13 @@ // @ts-check /* eslint-disable func-names */ /* eslint-env node */ -import { Command } from 'commander'; +import { makeRpcUtils } from '@agoric/client-utils'; import { lookupOfferIdForVault, Offers, } from '@agoric/inter-protocol/src/clientSupport.js'; +import { Command } from 'commander'; import { normalizeAddressWithOptions } from '../lib/chain.js'; -import { makeRpcUtils } from '@agoric/client-utils'; import { getCurrent, outputExecuteOfferAction } from '../lib/wallet.js'; /** diff --git a/packages/agoric-cli/src/commands/wallet.js b/packages/agoric-cli/src/commands/wallet.js index f01764d9b6d..48f747cedf1 100644 --- a/packages/agoric-cli/src/commands/wallet.js +++ b/packages/agoric-cli/src/commands/wallet.js @@ -8,11 +8,15 @@ import { makeLeader, makeLeaderFromRpcAddresses, } from '@agoric/casting'; +import { + fmtRecordOfLines, + makeRpcUtils, + networkConfig, + summarize, +} from '@agoric/client-utils'; +import { execFileSync } from 'child_process'; import fs from 'fs'; import util from 'util'; -import { execFileSync } from 'child_process'; -import { fmtRecordOfLines, summarize } from '@agoric/client-utils'; -import { makeRpcUtils, networkConfig } from '@agoric/client-utils'; import { makeLeaderOptions } from '../lib/casting.js'; import { diff --git a/packages/agoric-cli/src/lib/wallet.js b/packages/agoric-cli/src/lib/wallet.js index 36ac0e01038..e4728597591 100644 --- a/packages/agoric-cli/src/lib/wallet.js +++ b/packages/agoric-cli/src/lib/wallet.js @@ -1,10 +1,10 @@ // @ts-check /* eslint-env node */ -import { Fail } from '@endo/errors'; import { iterateReverse } from '@agoric/casting'; -import { makeWalletStateCoalescer } from '@agoric/smart-wallet/src/utils.js'; import { boardSlottingMarshaller, makeRpcUtils } from '@agoric/client-utils'; +import { makeWalletStateCoalescer } from '@agoric/smart-wallet/src/utils.js'; +import { Fail } from '@endo/errors'; import { execSwingsetTransaction, pollBlocks, pollTx } from './chain.js'; /** diff --git a/packages/agoric-cli/test/inter-cli.test.js b/packages/agoric-cli/test/inter-cli.test.js index 4d2ffa2c752..ab3d6c92288 100644 --- a/packages/agoric-cli/test/inter-cli.test.js +++ b/packages/agoric-cli/test/inter-cli.test.js @@ -2,14 +2,11 @@ /* eslint-env node */ import '@endo/init'; import test from 'ava'; -import { createCommand, CommanderError } from 'commander'; +import { CommanderError, createCommand } from 'commander'; -import { Far } from '@endo/far'; +import { boardSlottingMarshaller, makeFromBoard } from '@agoric/client-utils'; import { makeParseAmount } from '@agoric/inter-protocol/src/clientSupport.js'; -import { - boardSlottingMarshaller, - makeFromBoard, -} from '../../client-utils/src/rpc.js'; +import { Far } from '@endo/far'; import { fmtBid, makeInterCommand } from '../src/commands/inter.js'; From 20083ae6cf3b479ca68aa7b81415157aceca38fe Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Mon, 4 Nov 2024 11:49:00 -0800 Subject: [PATCH 10/19] feat: makeWalletUtils wo/spawn --- packages/agoric-cli/src/commands/inter.js | 10 +- packages/agoric-cli/src/commands/oracle.js | 7 +- .../agoric-cli/src/commands/test-upgrade.js | 10 +- packages/agoric-cli/src/lib/wallet.js | 84 +--------------- packages/client-utils/src/chain.js | 53 ++++++++++ packages/client-utils/src/main.js | 1 + packages/client-utils/src/wallet-utils.js | 96 +++++++++++++++++++ 7 files changed, 167 insertions(+), 94 deletions(-) create mode 100644 packages/client-utils/src/chain.js create mode 100644 packages/client-utils/src/wallet-utils.js diff --git a/packages/agoric-cli/src/commands/inter.js b/packages/agoric-cli/src/commands/inter.js index 9b0f6b65cc3..62dd0cd6246 100644 --- a/packages/agoric-cli/src/commands/inter.js +++ b/packages/agoric-cli/src/commands/inter.js @@ -10,6 +10,7 @@ import { bigintReplacer, getNetworkConfig, makeAmountFormatter, + makeWalletUtils, } from '@agoric/client-utils'; import { makeOfferSpecShape } from '@agoric/inter-protocol/src/auction/auctionBook.js'; import { Offers } from '@agoric/inter-protocol/src/clientSupport.js'; @@ -17,12 +18,7 @@ import { objectMap } from '@agoric/internal'; import { M, matches } from '@endo/patterns'; import { normalizeAddressWithOptions, pollBlocks } from '../lib/chain.js'; -import { - getCurrent, - makeWalletUtils, - outputActionAndHint, - sendAction, -} from '../lib/wallet.js'; +import { getCurrent, outputActionAndHint, sendAction } from '../lib/wallet.js'; const { values } = Object; @@ -238,7 +234,7 @@ export const makeInterCommand = ( // XXX pass fetch to getNetworkConfig() explicitly // await null above makes this await safe const networkConfig = await getNetworkConfig(env); - return makeWalletUtils({ fetch, execFileSync, delay }, networkConfig); + return makeWalletUtils({ fetch, delay }, networkConfig); } catch (err) { // CommanderError is a class constructor, and so // must be invoked with `new`. diff --git a/packages/agoric-cli/src/commands/oracle.js b/packages/agoric-cli/src/commands/oracle.js index 3873420cc73..c2679698a2a 100644 --- a/packages/agoric-cli/src/commands/oracle.js +++ b/packages/agoric-cli/src/commands/oracle.js @@ -5,6 +5,7 @@ import { bigintReplacer, getNetworkConfig, makeRpcUtils, + makeWalletUtils, storageHelper, } from '@agoric/client-utils'; import { Offers } from '@agoric/inter-protocol/src/clientSupport.js'; @@ -17,7 +18,6 @@ import { inspect } from 'util'; import { normalizeAddressWithOptions } from '../lib/chain.js'; import { getCurrent, - makeWalletUtils, outputAction, sendAction, sendHint, @@ -271,10 +271,7 @@ export const makeOracleCommand = (logger, io = {}) => { ) => { const { readLatestHead, networkConfig, lookupPriceAggregatorInstance } = await rpcTools(); - const wutil = await makeWalletUtils( - { fetch, execFileSync, delay }, - networkConfig, - ); + const wutil = await makeWalletUtils({ fetch, delay }, networkConfig); const unitPrice = scaleDecimals(price); const feedPath = `published.priceFeed.${pair[0]}-${pair[1]}_price_feed`; diff --git a/packages/agoric-cli/src/commands/test-upgrade.js b/packages/agoric-cli/src/commands/test-upgrade.js index b173e2991cd..1c05d611ba3 100644 --- a/packages/agoric-cli/src/commands/test-upgrade.js +++ b/packages/agoric-cli/src/commands/test-upgrade.js @@ -1,10 +1,14 @@ // @ts-check /* eslint-env node */ -import { bigintReplacer, getNetworkConfig } from '@agoric/client-utils'; +import { + bigintReplacer, + getNetworkConfig, + makeWalletUtils, +} from '@agoric/client-utils'; import { Fail } from '@endo/errors'; import { CommanderError } from 'commander'; import { normalizeAddressWithOptions } from '../lib/chain.js'; -import { makeWalletUtils, sendAction } from '../lib/wallet.js'; +import { sendAction } from '../lib/wallet.js'; /** * Make commands for testing. @@ -38,7 +42,7 @@ export const makeTestCommand = ( // XXX pass fetch to getNetworkConfig() explicitly // await null above makes this await safe const networkConfig = await getNetworkConfig(env); - return makeWalletUtils({ fetch, execFileSync, delay }, networkConfig); + return makeWalletUtils({ fetch, delay }, networkConfig); } catch (err) { // CommanderError is a class constructor, and so // must be invoked with `new`. diff --git a/packages/agoric-cli/src/lib/wallet.js b/packages/agoric-cli/src/lib/wallet.js index e4728597591..63ac4597373 100644 --- a/packages/agoric-cli/src/lib/wallet.js +++ b/packages/agoric-cli/src/lib/wallet.js @@ -2,10 +2,10 @@ /* eslint-env node */ import { iterateReverse } from '@agoric/casting'; -import { boardSlottingMarshaller, makeRpcUtils } from '@agoric/client-utils'; +import { boardSlottingMarshaller } from '@agoric/client-utils'; import { makeWalletStateCoalescer } from '@agoric/smart-wallet/src/utils.js'; import { Fail } from '@endo/errors'; -import { execSwingsetTransaction, pollBlocks, pollTx } from './chain.js'; +import { execSwingsetTransaction, pollTx } from './chain.js'; /** * @import {CurrentWalletRecord} from '@agoric/smart-wallet/src/smartWallet.js'; @@ -25,7 +25,7 @@ const emptyCurrentRecord = { /** * @param {string} addr - * @param {Pick} io + * @param {Pick} io * @returns {Promise} */ export const getCurrent = async (addr, { readLatestHead }) => { @@ -60,7 +60,7 @@ export const getCurrent = async (addr, { readLatestHead }) => { /** * @param {string} addr - * @param {Pick} io + * @param {Pick} io * @returns {Promise} */ export const getLastUpdate = (addr, { readLatestHead }) => { @@ -145,7 +145,7 @@ export const coalesceWalletState = async (follower, invitationBrand) => { * * @throws { Error & { code: number } } if transaction fails * @param {import('@agoric/smart-wallet/src/smartWallet.js').BridgeAction} bridgeAction - * @param {import('@agoric/client-utils').MinimalNetworkConfig & { + * @param {MinimalNetworkConfig & { * from: string, * fees?: string, * verbose?: boolean, @@ -214,77 +214,3 @@ export const findContinuingIds = (current, agoricNames) => { } return found; }; - -export const makeWalletUtils = async ( - { fetch, execFileSync, delay }, - networkConfig, -) => { - const { agoricNames, fromBoard, readLatestHead, vstorage } = - await makeRpcUtils({ fetch }, networkConfig); - /** - * @param {string} from - * @param {number|string} [minHeight] - */ - const storedWalletState = async (from, minHeight = undefined) => { - const m = boardSlottingMarshaller(fromBoard.convertSlotToVal); - - const history = await vstorage.readFully( - `published.wallet.${from}`, - minHeight, - ); - - /** @type {{ Invitation: Brand<'set'> }} */ - // @ts-expect-error XXX how to narrow AssetKind to set? - const { Invitation } = agoricNames.brand; - const coalescer = makeWalletStateCoalescer(Invitation); - // update with oldest first - for (const txt of history.reverse()) { - const { body, slots } = JSON.parse(txt); - const record = m.fromCapData({ body, slots }); - coalescer.update(record); - } - const coalesced = coalescer.state; - harden(coalesced); - return coalesced; - }; - - /** - * Get OfferStatus by id, polling until available. - * - * @param {string} from - * @param {string|number} id - * @param {number|string} minHeight - * @param {boolean} [untilNumWantsSatisfied] - */ - const pollOffer = async ( - from, - id, - minHeight, - untilNumWantsSatisfied = false, - ) => { - const lookup = async () => { - const { offerStatuses } = await storedWalletState(from, minHeight); - const offerStatus = [...offerStatuses.values()].find(s => s.id === id); - if (!offerStatus) throw Error('retry'); - harden(offerStatus); - if (untilNumWantsSatisfied && !('numWantsSatisfied' in offerStatus)) { - throw Error('retry (no numWantsSatisfied yet)'); - } - return offerStatus; - }; - const retryMessage = 'offer not in wallet at block'; - const opts = { ...networkConfig, execFileSync, delay, retryMessage }; - return pollBlocks(opts)(lookup); - }; - - return { - networkConfig, - agoricNames, - fromBoard, - vstorage, - readLatestHead, - storedWalletState, - pollOffer, - }; -}; -/** @typedef {Awaited>} WalletUtils */ diff --git a/packages/client-utils/src/chain.js b/packages/client-utils/src/chain.js new file mode 100644 index 00000000000..3b9caca79e3 --- /dev/null +++ b/packages/client-utils/src/chain.js @@ -0,0 +1,53 @@ +/** + * @import {MinimalNetworkConfig} from '@agoric/client-utils'; + */ + +import { StargateClient } from '@cosmjs/stargate'; + +/** + * @param {MinimalNetworkConfig} config + * @returns {Promise} + */ +export const makeStargateClient = async config => { + // TODO distribute load + const endpoint = config.rpcAddrs.at(-1); + assert(endpoint, 'no endpoints'); + + return StargateClient.connect(endpoint); +}; + +/** + * @param {{ + * client: StargateClient, + * delay: (ms: number) => Promise, + * period?: number, + * retryMessage?: string, + * }} opts + * @returns {(l: (b: { time: string, height: number }) => Promise) => Promise} + */ +export const pollBlocks = opts => async lookup => { + const { client, delay, period = 3 * 1000 } = opts; + const { retryMessage } = opts; + + await null; // separate sync prologue + + for (;;) { + const status = await client.getBlock(); + const { + header: { time, height }, + } = status; + try { + // see await null above + const result = await lookup({ time, height }); + return result; + } catch (_err) { + console.error( + time, + retryMessage || 'not in block', + height, + 'retrying...', + ); + await delay(period); + } + } +}; diff --git a/packages/client-utils/src/main.js b/packages/client-utils/src/main.js index dca5f6810db..4e0632a2045 100644 --- a/packages/client-utils/src/main.js +++ b/packages/client-utils/src/main.js @@ -1,2 +1,3 @@ export * from './format.js'; export * from './rpc.js'; +export * from './wallet-utils.js'; diff --git a/packages/client-utils/src/wallet-utils.js b/packages/client-utils/src/wallet-utils.js new file mode 100644 index 00000000000..9ad670093d8 --- /dev/null +++ b/packages/client-utils/src/wallet-utils.js @@ -0,0 +1,96 @@ +import { makeWalletStateCoalescer } from '@agoric/smart-wallet/src/utils.js'; +import { makeStargateClient, pollBlocks } from './chain.js'; +import { boardSlottingMarshaller, makeRpcUtils } from './rpc.js'; + +/** + * @import {Amount, Brand} from '@agoric/ertp/src/types.js' + */ + +export const makeWalletUtils = async ({ fetch, delay }, networkConfig) => { + const { agoricNames, fromBoard, marshaller, readLatestHead, vstorage } = + await makeRpcUtils({ fetch }, networkConfig); + + const client = await makeStargateClient(networkConfig); + + /** + * @param {string} from + * @param {number|string} [minHeight] + */ + const storedWalletState = async (from, minHeight = undefined) => { + const m = boardSlottingMarshaller(fromBoard.convertSlotToVal); + + const history = await vstorage.readFully( + `published.wallet.${from}`, + minHeight, + ); + + /** @type {{ Invitation: Brand<'set'> }} */ + // @ts-expect-error XXX how to narrow AssetKind to set? + const { Invitation } = agoricNames.brand; + const coalescer = makeWalletStateCoalescer(Invitation); + // update with oldest first + for (const txt of history.reverse()) { + const { body, slots } = JSON.parse(txt); + const record = m.fromCapData({ body, slots }); + coalescer.update(record); + } + const coalesced = coalescer.state; + harden(coalesced); + return coalesced; + }; + + /** + * Get OfferStatus by id, polling until available. + * + * @param {string} from + * @param {string|number} id + * @param {number|string} minHeight + * @param {boolean} [untilNumWantsSatisfied] + */ + const pollOffer = async ( + from, + id, + minHeight, + untilNumWantsSatisfied = false, + ) => { + const poll = pollBlocks({ + client, + delay, + retryMessage: 'offer not in wallet at block', + }); + + const lookup = async () => { + const { offerStatuses } = await storedWalletState(from, minHeight); + const offerStatus = [...offerStatuses.values()].find(s => s.id === id); + if (!offerStatus) throw Error('retry'); + harden(offerStatus); + if (untilNumWantsSatisfied && !('numWantsSatisfied' in offerStatus)) { + throw Error('retry (no numWantsSatisfied yet)'); + } + return offerStatus; + }; + return poll(lookup); + }; + + /** + * @param {string} addr + * @returns {Promise} + */ + const getLastUpdate = addr => { + // @ts-expect-error cast + return readLatestHead(`published.wallet.${addr}`); + }; + + return { + networkConfig, + agoricNames, + fromBoard, + marshaller, + vstorage, + getLastUpdate, + readLatestHead, + storedWalletState, + pollOffer, + }; +}; +/** @typedef {Awaited>} WalletUtils */ From 576241810841ec4351375ba3f5e7d54891ee758c Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Tue, 5 Nov 2024 15:54:39 -0800 Subject: [PATCH 11/19] refactor: pickEndpoint --- packages/client-utils/src/chain.js | 10 +++------- packages/client-utils/src/rpc.js | 3 +++ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/client-utils/src/chain.js b/packages/client-utils/src/chain.js index 3b9caca79e3..4cfa4bcb620 100644 --- a/packages/client-utils/src/chain.js +++ b/packages/client-utils/src/chain.js @@ -3,18 +3,14 @@ */ import { StargateClient } from '@cosmjs/stargate'; +import { pickEndpoint } from './rpc.js'; /** * @param {MinimalNetworkConfig} config * @returns {Promise} */ -export const makeStargateClient = async config => { - // TODO distribute load - const endpoint = config.rpcAddrs.at(-1); - assert(endpoint, 'no endpoints'); - - return StargateClient.connect(endpoint); -}; +export const makeStargateClient = config => + StargateClient.connect(pickEndpoint(config)); /** * @param {{ diff --git a/packages/client-utils/src/rpc.js b/packages/client-utils/src/rpc.js index f25e68a1fbb..debd9b25c2b 100644 --- a/packages/client-utils/src/rpc.js +++ b/packages/client-utils/src/rpc.js @@ -48,6 +48,9 @@ export const getNetworkConfig = async env => { }); }; +// TODO distribute load +export const pickEndpoint = ({ rpcAddrs }) => rpcAddrs[0]; + /** @type {MinimalNetworkConfig} */ const networkConfig = await getNetworkConfig(process.env); export { networkConfig }; From 55fd3d15d110a5baca33c895ce0ef5040884b2e9 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Wed, 6 Nov 2024 10:11:47 -0800 Subject: [PATCH 12/19] refactor: network-config ocap module --- packages/agoric-cli/src/commands/auction.js | 10 +++- packages/agoric-cli/src/commands/gov.js | 25 ++++++---- packages/agoric-cli/src/commands/inter.js | 4 +- packages/agoric-cli/src/commands/oracle.js | 6 +-- packages/agoric-cli/src/commands/perf.js | 8 +-- packages/agoric-cli/src/commands/psm.js | 5 +- packages/agoric-cli/src/commands/reserve.js | 9 ++-- .../agoric-cli/src/commands/test-upgrade.js | 9 ++-- packages/agoric-cli/src/commands/vaults.js | 17 +++++-- packages/agoric-cli/src/commands/wallet.js | 20 +++++--- packages/agoric-cli/src/lib/network-config.js | 37 ++++++++++++++ packages/client-utils/src/format.js | 2 - packages/client-utils/src/rpc.js | 49 ++----------------- 13 files changed, 112 insertions(+), 89 deletions(-) create mode 100644 packages/agoric-cli/src/lib/network-config.js diff --git a/packages/agoric-cli/src/commands/auction.js b/packages/agoric-cli/src/commands/auction.js index ce3a0f63f53..241b49ec28c 100644 --- a/packages/agoric-cli/src/commands/auction.js +++ b/packages/agoric-cli/src/commands/auction.js @@ -1,15 +1,18 @@ // @ts-check - +/* eslint-env node */ import { InvalidArgumentError } from 'commander'; import { Fail } from '@endo/errors'; import { makeRpcUtils } from '@agoric/client-utils'; import { outputActionAndHint } from '../lib/wallet.js'; +import { getNetworkConfig } from '../lib/network-config.js'; /** * @import {ParamTypesMap, ParamTypesMapFromRecord} from '@agoric/governance/src/contractGovernance/typedParamManager.js' * @import {ParamValueForType} from '@agoric/governance/src/types.js' */ +const networkConfig = await getNetworkConfig({ env: process.env, fetch }); + /** * @template {ParamTypesMap} M * @typedef {{ @@ -86,7 +89,10 @@ export const makeAuctionCommand = ( * }} opts */ async opts => { - const { agoricNames, readLatestHead } = await makeRpcUtils({ fetch }); + const { agoricNames, readLatestHead } = await makeRpcUtils( + { fetch }, + networkConfig, + ); /** @type {{ current: AuctionParamRecord }} */ // @ts-expect-error XXX should runtime check? diff --git a/packages/agoric-cli/src/commands/gov.js b/packages/agoric-cli/src/commands/gov.js index 27f15e830e9..fd0efc504ef 100644 --- a/packages/agoric-cli/src/commands/gov.js +++ b/packages/agoric-cli/src/commands/gov.js @@ -1,10 +1,11 @@ // @ts-check /* eslint-disable func-names */ -/* global globalThis, process, setTimeout */ -import { getNetworkConfig, makeRpcUtils } from '@agoric/client-utils'; +/* eslint-env node */ +import { makeRpcUtils } from '@agoric/client-utils'; import { execFileSync as execFileSyncAmbient } from 'child_process'; import { Command, CommanderError } from 'commander'; import { normalizeAddressWithOptions, pollBlocks } from '../lib/chain.js'; +import { getNetworkConfig } from '../lib/network-config.js'; import { findContinuingIds, getCurrent, @@ -25,6 +26,8 @@ const collectValues = (val, memo) => { const defaultKeyring = process.env.AGORIC_KEYRING_BACKEND || 'test'; +const networkConfig = await getNetworkConfig({ env: process.env, fetch }); + /** * @param {import('anylogger').Logger} _logger * @param {{ @@ -40,10 +43,9 @@ export const makeGovCommand = (_logger, io = {}) => { const { // Allow caller to provide access explicitly, but // default to conventional ambient IO facilities. - env = process.env, stdout = process.stdout, stderr = process.stderr, - fetch = globalThis.fetch, + fetch = global.fetch, execFileSync = execFileSyncAmbient, delay = ms => new Promise(resolve => setTimeout(resolve, ms)), } = io; @@ -95,8 +97,7 @@ export const makeGovCommand = (_logger, io = {}) => { { toOffer, sendFrom, keyringBackend }, optUtils, ) { - const networkConfig = await getNetworkConfig(env); - const utils = await (optUtils || makeRpcUtils({ fetch })); + const utils = await (optUtils || makeRpcUtils({ fetch }, networkConfig)); const { agoricNames, readLatestHead } = utils; assert(keyringBackend, 'missing keyring-backend option'); @@ -264,7 +265,10 @@ export const makeGovCommand = (_logger, io = {}) => { ) .requiredOption('--for ', 'description of the invitation') .action(async opts => { - const { agoricNames, readLatestHead } = await makeRpcUtils({ fetch }); + const { agoricNames, readLatestHead } = await makeRpcUtils( + { fetch }, + networkConfig, + ); const current = await getCurrent(opts.from, { readLatestHead }); const known = findContinuingIds(current, agoricNames); @@ -290,7 +294,10 @@ export const makeGovCommand = (_logger, io = {}) => { normalizeAddress, ) .action(async opts => { - const { agoricNames, readLatestHead } = await makeRpcUtils({ fetch }); + const { agoricNames, readLatestHead } = await makeRpcUtils( + { fetch }, + networkConfig, + ); const current = await getCurrent(opts.from, { readLatestHead }); const found = findContinuingIds(current, agoricNames); @@ -326,7 +333,7 @@ export const makeGovCommand = (_logger, io = {}) => { normalizeAddress, ) .action(async function (opts, options) { - const utils = await makeRpcUtils({ fetch }); + const utils = await makeRpcUtils({ fetch }, networkConfig); const { readLatestHead } = utils; const info = await readLatestHead( diff --git a/packages/agoric-cli/src/commands/inter.js b/packages/agoric-cli/src/commands/inter.js index 62dd0cd6246..b3655afd3f3 100644 --- a/packages/agoric-cli/src/commands/inter.js +++ b/packages/agoric-cli/src/commands/inter.js @@ -8,7 +8,6 @@ import { CommanderError, InvalidArgumentError } from 'commander'; import { asBoardRemote, bigintReplacer, - getNetworkConfig, makeAmountFormatter, makeWalletUtils, } from '@agoric/client-utils'; @@ -18,6 +17,7 @@ import { objectMap } from '@agoric/internal'; import { M, matches } from '@endo/patterns'; import { normalizeAddressWithOptions, pollBlocks } from '../lib/chain.js'; +import { getNetworkConfig } from '../lib/network-config.js'; import { getCurrent, outputActionAndHint, sendAction } from '../lib/wallet.js'; const { values } = Object; @@ -233,7 +233,7 @@ export const makeInterCommand = ( try { // XXX pass fetch to getNetworkConfig() explicitly // await null above makes this await safe - const networkConfig = await getNetworkConfig(env); + const networkConfig = await getNetworkConfig({ env, fetch }); return makeWalletUtils({ fetch, delay }, networkConfig); } catch (err) { // CommanderError is a class constructor, and so diff --git a/packages/agoric-cli/src/commands/oracle.js b/packages/agoric-cli/src/commands/oracle.js index c2679698a2a..30588137f96 100644 --- a/packages/agoric-cli/src/commands/oracle.js +++ b/packages/agoric-cli/src/commands/oracle.js @@ -3,7 +3,6 @@ /* eslint-env node */ import { bigintReplacer, - getNetworkConfig, makeRpcUtils, makeWalletUtils, storageHelper, @@ -16,6 +15,7 @@ import * as cp from 'child_process'; import { Command } from 'commander'; import { inspect } from 'util'; import { normalizeAddressWithOptions } from '../lib/chain.js'; +import { getNetworkConfig } from '../lib/network-config.js'; import { getCurrent, outputAction, @@ -86,8 +86,8 @@ export const makeOracleCommand = (logger, io = {}) => { const rpcTools = async () => { // XXX pass fetch to getNetworkConfig() explicitly - const networkConfig = await getNetworkConfig(env); - const utils = await makeRpcUtils({ fetch }); + const networkConfig = await getNetworkConfig({ env: process.env, fetch }); + const utils = await makeRpcUtils({ fetch }, networkConfig); const lookupPriceAggregatorInstance = ([brandIn, brandOut]) => { const name = oracleBrandFeedName(brandIn, brandOut); diff --git a/packages/agoric-cli/src/commands/perf.js b/packages/agoric-cli/src/commands/perf.js index ab36deee106..ef4ee2b531e 100644 --- a/packages/agoric-cli/src/commands/perf.js +++ b/packages/agoric-cli/src/commands/perf.js @@ -7,21 +7,23 @@ import { makeFollower, makeLeaderFromRpcAddresses, } from '@agoric/casting'; +import { slotToRemotable } from '@agoric/internal/src/storage-test-utils.js'; +import { boardSlottingMarshaller } from '@agoric/vats/tools/board-utils.js'; import { Command } from 'commander'; import fs from 'fs'; import { exit } from 'process'; -import { networkConfig } from '@agoric/client-utils'; -import { slotToRemotable } from '@agoric/internal/src/storage-test-utils.js'; -import { boardSlottingMarshaller } from '@agoric/vats/tools/board-utils.js'; import { makeLeaderOptions } from '../lib/casting.js'; import { execSwingsetTransaction, normalizeAddressWithOptions, } from '../lib/chain.js'; +import { getNetworkConfig } from '../lib/network-config.js'; // tight for perf testing but less than this tends to hang. const SLEEP_SECONDS = 0.1; +const networkConfig = await getNetworkConfig({ env: process.env, fetch }); + /** * @param {import('anylogger').Logger} logger */ diff --git a/packages/agoric-cli/src/commands/psm.js b/packages/agoric-cli/src/commands/psm.js index b2236b58580..4a5d2cc6fab 100644 --- a/packages/agoric-cli/src/commands/psm.js +++ b/packages/agoric-cli/src/commands/psm.js @@ -4,8 +4,11 @@ import { asPercent, makeRpcUtils, storageHelper } from '@agoric/client-utils'; import { Offers } from '@agoric/inter-protocol/src/clientSupport.js'; import { Command } from 'commander'; +import { getNetworkConfig } from '../lib/network-config.js'; import { outputExecuteOfferAction } from '../lib/wallet.js'; +const networkConfig = await getNetworkConfig({ env: process.env, fetch }); + // Adapted from https://gist.github.com/dckc/8b5b2f16395cb4d7f2ff340e0bc6b610#file-psm-tool /** @@ -59,7 +62,7 @@ export const makePsmCommand = logger => { ); const rpcTools = async () => { - const utils = await makeRpcUtils({ fetch }); + const utils = await makeRpcUtils({ fetch }, networkConfig); const lookupPsmInstance = ([minted, anchor]) => { const name = `psm-${minted}-${anchor}`; diff --git a/packages/agoric-cli/src/commands/reserve.js b/packages/agoric-cli/src/commands/reserve.js index 396dffb4af5..cb510283952 100644 --- a/packages/agoric-cli/src/commands/reserve.js +++ b/packages/agoric-cli/src/commands/reserve.js @@ -1,11 +1,14 @@ // @ts-check /* eslint-disable func-names */ /* eslint-env node */ +import { makeRpcUtils } from '@agoric/client-utils'; import { Offers } from '@agoric/inter-protocol/src/clientSupport.js'; import { Command } from 'commander'; -import { makeRpcUtils } from '@agoric/client-utils'; +import { getNetworkConfig } from '../lib/network-config.js'; import { outputActionAndHint } from '../lib/wallet.js'; +const networkConfig = await getNetworkConfig({ env: process.env, fetch }); + /** * @param {import('anylogger').Logger} _logger * @param {*} io @@ -29,7 +32,7 @@ export const makeReserveCommand = (_logger, io = {}) => { * }} opts */ async ({ collateralBrand, ...opts }) => { - const { agoricNames } = await makeRpcUtils({ fetch }); + const { agoricNames } = await makeRpcUtils({ fetch }, networkConfig); const offer = Offers.reserve.AddCollateral(agoricNames, { collateralBrandKey: collateralBrand, @@ -63,7 +66,7 @@ export const makeReserveCommand = (_logger, io = {}) => { 1, ) .action(async function (opts) { - const { agoricNames } = await makeRpcUtils({ fetch }); + const { agoricNames } = await makeRpcUtils({ fetch }, networkConfig); const reserveInstance = agoricNames.instance.reserve; assert(reserveInstance, 'missing reserve in names'); diff --git a/packages/agoric-cli/src/commands/test-upgrade.js b/packages/agoric-cli/src/commands/test-upgrade.js index 1c05d611ba3..91565fe81d2 100644 --- a/packages/agoric-cli/src/commands/test-upgrade.js +++ b/packages/agoric-cli/src/commands/test-upgrade.js @@ -1,13 +1,10 @@ // @ts-check /* eslint-env node */ -import { - bigintReplacer, - getNetworkConfig, - makeWalletUtils, -} from '@agoric/client-utils'; +import { bigintReplacer, makeWalletUtils } from '@agoric/client-utils'; import { Fail } from '@endo/errors'; import { CommanderError } from 'commander'; import { normalizeAddressWithOptions } from '../lib/chain.js'; +import { getNetworkConfig } from '../lib/network-config.js'; import { sendAction } from '../lib/wallet.js'; /** @@ -41,7 +38,7 @@ export const makeTestCommand = ( try { // XXX pass fetch to getNetworkConfig() explicitly // await null above makes this await safe - const networkConfig = await getNetworkConfig(env); + const networkConfig = await getNetworkConfig({ env, fetch }); return makeWalletUtils({ fetch, delay }, networkConfig); } catch (err) { // CommanderError is a class constructor, and so diff --git a/packages/agoric-cli/src/commands/vaults.js b/packages/agoric-cli/src/commands/vaults.js index 4953351aa45..bc076b0f9bb 100644 --- a/packages/agoric-cli/src/commands/vaults.js +++ b/packages/agoric-cli/src/commands/vaults.js @@ -9,6 +9,9 @@ import { import { Command } from 'commander'; import { normalizeAddressWithOptions } from '../lib/chain.js'; import { getCurrent, outputExecuteOfferAction } from '../lib/wallet.js'; +import { getNetworkConfig } from '../lib/network-config.js'; + +const networkConfig = await getNetworkConfig({ env: process.env, fetch }); /** * @param {import('anylogger').Logger} logger @@ -36,7 +39,7 @@ export const makeVaultsCommand = logger => { normalizeAddress, ) .action(async function (opts) { - const { readLatestHead } = await makeRpcUtils({ fetch }); + const { readLatestHead } = await makeRpcUtils({ fetch }, networkConfig); const current = await getCurrent(opts.from, { readLatestHead, @@ -61,7 +64,7 @@ export const makeVaultsCommand = logger => { .option('--collateralBrand ', 'Collateral brand key', 'ATOM') .action(async function (opts) { logger.warn('running with options', opts); - const { agoricNames } = await makeRpcUtils({ fetch }); + const { agoricNames } = await makeRpcUtils({ fetch }, networkConfig); const offer = Offers.vaults.OpenVault(agoricNames, { giveCollateral: opts.giveCollateral, @@ -96,7 +99,10 @@ export const makeVaultsCommand = logger => { .requiredOption('--vaultId ', 'Key of vault (e.g. vault1)') .action(async function (opts) { logger.warn('running with options', opts); - const { agoricNames, readLatestHead } = await makeRpcUtils({ fetch }); + const { agoricNames, readLatestHead } = await makeRpcUtils( + { fetch }, + networkConfig, + ); const previousOfferId = await lookupOfferIdForVault( opts.vaultId, @@ -137,7 +143,10 @@ export const makeVaultsCommand = logger => { ) .action(async function (opts) { logger.warn('running with options', opts); - const { agoricNames, readLatestHead } = await makeRpcUtils({ fetch }); + const { agoricNames, readLatestHead } = await makeRpcUtils( + { fetch }, + networkConfig, + ); const previousOfferId = await lookupOfferIdForVault( opts.vaultId, diff --git a/packages/agoric-cli/src/commands/wallet.js b/packages/agoric-cli/src/commands/wallet.js index 48f747cedf1..0fb08676b34 100644 --- a/packages/agoric-cli/src/commands/wallet.js +++ b/packages/agoric-cli/src/commands/wallet.js @@ -11,7 +11,6 @@ import { import { fmtRecordOfLines, makeRpcUtils, - networkConfig, summarize, } from '@agoric/client-utils'; import { execFileSync } from 'child_process'; @@ -24,8 +23,11 @@ import { fetchSwingsetParams, normalizeAddressWithOptions, } from '../lib/chain.js'; +import { getNetworkConfig } from '../lib/network-config.js'; import { coalesceWalletState, getCurrent } from '../lib/wallet.js'; +const networkConfig = await getNetworkConfig({ env: process.env, fetch }); + const SLEEP_SECONDS = 3; /** @@ -106,7 +108,7 @@ export const makeWalletCommand = async command => { .action(async function (opts) { const offerStr = fs.readFileSync(opts.file).toString(); - const { unserializer } = await makeRpcUtils({ fetch }); + const { unserializer } = await makeRpcUtils({ fetch }, networkConfig); const offerObj = unserializer.fromCapData(JSON.parse(offerStr)); console.log(offerObj); @@ -121,7 +123,7 @@ export const makeWalletCommand = async command => { .action(async function (opts) { const offerStr = fs.readFileSync(opts.offer).toString(); - const { unserializer } = await makeRpcUtils({ fetch }); + const { unserializer } = await makeRpcUtils({ fetch }, networkConfig); const offerObj = unserializer.fromCapData(JSON.parse(offerStr)); console.log(offerObj.offer.id); @@ -159,7 +161,7 @@ export const makeWalletCommand = async command => { .command('list') .description('list all wallets in vstorage') .action(async function () { - const { vstorage } = await makeRpcUtils({ fetch }); + const { vstorage } = await makeRpcUtils({ fetch }, networkConfig); const wallets = await vstorage.keys('published.wallet'); process.stdout.write(wallets.join('\n')); }); @@ -173,16 +175,18 @@ export const makeWalletCommand = async command => { normalizeAddress, ) .action(async function (opts) { - const { agoricNames, unserializer, readLatestHead } = await makeRpcUtils({ - fetch, - }); + const { agoricNames, unserializer, readLatestHead } = await makeRpcUtils( + { + fetch, + }, + networkConfig, + ); const leader = makeLeader(networkConfig.rpcAddrs[0]); const follower = await makeFollower( `:published.wallet.${opts.from}`, leader, { - // @ts-expect-error xxx unserializer, }, ); diff --git a/packages/agoric-cli/src/lib/network-config.js b/packages/agoric-cli/src/lib/network-config.js new file mode 100644 index 00000000000..ca0485383f8 --- /dev/null +++ b/packages/agoric-cli/src/lib/network-config.js @@ -0,0 +1,37 @@ +import { NonNullish } from '@agoric/internal'; + +export const networkConfigUrl = agoricNetSubdomain => + `https://${agoricNetSubdomain}.agoric.net/network-config`; +export const rpcUrl = agoricNetSubdomain => + `https://${agoricNetSubdomain}.rpc.agoric.net:443`; + +/** + * @param {string} str + * @param {{ fetch: typeof fetch }} io + * @returns {Promise} + */ +const fromAgoricNet = (str, { fetch }) => { + const [netName, chainName] = str.split(','); + if (chainName) { + return Promise.resolve({ chainName, rpcAddrs: [rpcUrl(netName)] }); + } + return fetch(networkConfigUrl(netName)).then(res => res.json()); +}; + +/** + * @param {{ env: typeof process.env, fetch: typeof fetch }} io + * @returns {Promise} + */ +export const getNetworkConfig = async ({ env, fetch }) => { + if (!('AGORIC_NET' in env) || env.AGORIC_NET === 'local') { + return { rpcAddrs: ['http://0.0.0.0:26657'], chainName: 'agoriclocal' }; + } + + return fromAgoricNet(NonNullish(env.AGORIC_NET), { fetch }).catch(err => { + throw Error( + `cannot get network config (${env.AGORIC_NET || 'local'}): ${ + err.message + }`, + ); + }); +}; diff --git a/packages/client-utils/src/format.js b/packages/client-utils/src/format.js index 2e91d5ddfd5..16ebe45308b 100644 --- a/packages/client-utils/src/format.js +++ b/packages/client-utils/src/format.js @@ -1,5 +1,3 @@ -// @ts-check - import { Fail, q } from '@endo/errors'; import { makeBoardRemote } from '@agoric/vats/tools/board-utils.js'; diff --git a/packages/client-utils/src/rpc.js b/packages/client-utils/src/rpc.js index debd9b25c2b..2b8ab1a85d8 100644 --- a/packages/client-utils/src/rpc.js +++ b/packages/client-utils/src/rpc.js @@ -1,7 +1,4 @@ -// @ts-check -/* eslint-env node */ - -import { NonNullish } from '@agoric/internal'; +/* global Buffer */ import { boardSlottingMarshaller, makeBoardRemote, @@ -9,59 +6,19 @@ import { export { boardSlottingMarshaller }; -export const networkConfigUrl = agoricNetSubdomain => - `https://${agoricNetSubdomain}.agoric.net/network-config`; -export const rpcUrl = agoricNetSubdomain => - `https://${agoricNetSubdomain}.rpc.agoric.net:443`; - /** * @typedef {{ rpcAddrs: string[], chainName: string }} MinimalNetworkConfig */ -/** - * @param {string} str - * @returns {Promise} - */ -const fromAgoricNet = str => { - const [netName, chainName] = str.split(','); - if (chainName) { - return Promise.resolve({ chainName, rpcAddrs: [rpcUrl(netName)] }); - } - return fetch(networkConfigUrl(netName)).then(res => res.json()); -}; - -/** - * @param {typeof process.env} env - * @returns {Promise} - */ -export const getNetworkConfig = async env => { - if (!('AGORIC_NET' in env) || env.AGORIC_NET === 'local') { - return { rpcAddrs: ['http://0.0.0.0:26657'], chainName: 'agoriclocal' }; - } - - return fromAgoricNet(NonNullish(env.AGORIC_NET)).catch(err => { - throw Error( - `cannot get network config (${env.AGORIC_NET || 'local'}): ${ - err.message - }`, - ); - }); -}; - // TODO distribute load export const pickEndpoint = ({ rpcAddrs }) => rpcAddrs[0]; -/** @type {MinimalNetworkConfig} */ -const networkConfig = await getNetworkConfig(process.env); -export { networkConfig }; -// console.warn('networkConfig', networkConfig); - /** * @param {object} powers * @param {typeof window.fetch} powers.fetch * @param {MinimalNetworkConfig} config */ -export const makeVStorage = (powers, config = networkConfig) => { +export const makeVStorage = (powers, config) => { /** @param {string} path */ const getJSON = path => { const url = config.rpcAddrs[0] + path; @@ -256,7 +213,7 @@ export const makeAgoricNames = async (ctx, vstorage) => { * @param {{ fetch: typeof window.fetch }} io * @param {MinimalNetworkConfig} config */ -export const makeRpcUtils = async ({ fetch }, config = networkConfig) => { +export const makeRpcUtils = async ({ fetch }, config) => { await null; try { const vstorage = makeVStorage({ fetch }, config); From 4ea3ec095bda24ef8fd662768c5ceca28c8f5b42 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Wed, 6 Nov 2024 10:24:05 -0800 Subject: [PATCH 13/19] refactor: format lib back to agoric-cli --- packages/agoric-cli/src/commands/inter.js | 12 ++++++------ packages/agoric-cli/src/commands/oracle.js | 2 +- packages/agoric-cli/src/commands/psm.js | 3 ++- packages/agoric-cli/src/commands/test-upgrade.js | 3 ++- packages/agoric-cli/src/commands/wallet.js | 7 ++----- .../src => agoric-cli/src/lib}/format.js | 0 packages/client-utils/src/main.js | 1 - 7 files changed, 13 insertions(+), 15 deletions(-) rename packages/{client-utils/src => agoric-cli/src/lib}/format.js (100%) diff --git a/packages/agoric-cli/src/commands/inter.js b/packages/agoric-cli/src/commands/inter.js index b3655afd3f3..2db02720deb 100644 --- a/packages/agoric-cli/src/commands/inter.js +++ b/packages/agoric-cli/src/commands/inter.js @@ -5,12 +5,7 @@ // @ts-check import { CommanderError, InvalidArgumentError } from 'commander'; -import { - asBoardRemote, - bigintReplacer, - makeAmountFormatter, - makeWalletUtils, -} from '@agoric/client-utils'; +import { makeWalletUtils } from '@agoric/client-utils'; import { makeOfferSpecShape } from '@agoric/inter-protocol/src/auction/auctionBook.js'; import { Offers } from '@agoric/inter-protocol/src/clientSupport.js'; import { objectMap } from '@agoric/internal'; @@ -19,6 +14,11 @@ import { M, matches } from '@endo/patterns'; import { normalizeAddressWithOptions, pollBlocks } from '../lib/chain.js'; import { getNetworkConfig } from '../lib/network-config.js'; import { getCurrent, outputActionAndHint, sendAction } from '../lib/wallet.js'; +import { + asBoardRemote, + makeAmountFormatter, + bigintReplacer, +} from '../lib/format.js'; const { values } = Object; diff --git a/packages/agoric-cli/src/commands/oracle.js b/packages/agoric-cli/src/commands/oracle.js index 30588137f96..43392ef912c 100644 --- a/packages/agoric-cli/src/commands/oracle.js +++ b/packages/agoric-cli/src/commands/oracle.js @@ -2,7 +2,6 @@ /* eslint-disable func-names */ /* eslint-env node */ import { - bigintReplacer, makeRpcUtils, makeWalletUtils, storageHelper, @@ -22,6 +21,7 @@ import { sendAction, sendHint, } from '../lib/wallet.js'; +import { bigintReplacer } from '../lib/format.js'; /** @import {PriceAuthority, PriceDescription, PriceQuote, PriceQuoteValue, PriceQuery,} from '@agoric/zoe/tools/types.js'; */ diff --git a/packages/agoric-cli/src/commands/psm.js b/packages/agoric-cli/src/commands/psm.js index 4a5d2cc6fab..1d00ec839d0 100644 --- a/packages/agoric-cli/src/commands/psm.js +++ b/packages/agoric-cli/src/commands/psm.js @@ -1,11 +1,12 @@ // @ts-check /* eslint-disable func-names */ /* eslint-env node */ -import { asPercent, makeRpcUtils, storageHelper } from '@agoric/client-utils'; +import { makeRpcUtils, storageHelper } from '@agoric/client-utils'; import { Offers } from '@agoric/inter-protocol/src/clientSupport.js'; import { Command } from 'commander'; import { getNetworkConfig } from '../lib/network-config.js'; import { outputExecuteOfferAction } from '../lib/wallet.js'; +import { asPercent } from '../lib/format.js'; const networkConfig = await getNetworkConfig({ env: process.env, fetch }); diff --git a/packages/agoric-cli/src/commands/test-upgrade.js b/packages/agoric-cli/src/commands/test-upgrade.js index 91565fe81d2..b9dd5d6e76d 100644 --- a/packages/agoric-cli/src/commands/test-upgrade.js +++ b/packages/agoric-cli/src/commands/test-upgrade.js @@ -1,11 +1,12 @@ // @ts-check /* eslint-env node */ -import { bigintReplacer, makeWalletUtils } from '@agoric/client-utils'; +import { makeWalletUtils } from '@agoric/client-utils'; import { Fail } from '@endo/errors'; import { CommanderError } from 'commander'; import { normalizeAddressWithOptions } from '../lib/chain.js'; import { getNetworkConfig } from '../lib/network-config.js'; import { sendAction } from '../lib/wallet.js'; +import { bigintReplacer } from '../lib/format.js'; /** * Make commands for testing. diff --git a/packages/agoric-cli/src/commands/wallet.js b/packages/agoric-cli/src/commands/wallet.js index 0fb08676b34..a40cd1d1744 100644 --- a/packages/agoric-cli/src/commands/wallet.js +++ b/packages/agoric-cli/src/commands/wallet.js @@ -8,11 +8,7 @@ import { makeLeader, makeLeaderFromRpcAddresses, } from '@agoric/casting'; -import { - fmtRecordOfLines, - makeRpcUtils, - summarize, -} from '@agoric/client-utils'; +import { makeRpcUtils } from '@agoric/client-utils'; import { execFileSync } from 'child_process'; import fs from 'fs'; import util from 'util'; @@ -25,6 +21,7 @@ import { } from '../lib/chain.js'; import { getNetworkConfig } from '../lib/network-config.js'; import { coalesceWalletState, getCurrent } from '../lib/wallet.js'; +import { summarize, fmtRecordOfLines } from '../lib/format.js'; const networkConfig = await getNetworkConfig({ env: process.env, fetch }); diff --git a/packages/client-utils/src/format.js b/packages/agoric-cli/src/lib/format.js similarity index 100% rename from packages/client-utils/src/format.js rename to packages/agoric-cli/src/lib/format.js diff --git a/packages/client-utils/src/main.js b/packages/client-utils/src/main.js index 4e0632a2045..d22b4429d57 100644 --- a/packages/client-utils/src/main.js +++ b/packages/client-utils/src/main.js @@ -1,3 +1,2 @@ -export * from './format.js'; export * from './rpc.js'; export * from './wallet-utils.js'; From 1563f0f8cd621152b59953be4177cc8245e10735 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Wed, 6 Nov 2024 10:27:49 -0800 Subject: [PATCH 14/19] chore: deprecations --- packages/client-utils/src/rpc.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/client-utils/src/rpc.js b/packages/client-utils/src/rpc.js index 2b8ab1a85d8..cf8121f3856 100644 --- a/packages/client-utils/src/rpc.js +++ b/packages/client-utils/src/rpc.js @@ -132,6 +132,7 @@ export const makeVStorage = (powers, config) => { }; /** @typedef {ReturnType} VStorage */ +/** @deprecated */ export const makeFromBoard = () => { const cache = new Map(); const convertSlotToVal = (boardId, iface) => { @@ -146,6 +147,7 @@ export const makeFromBoard = () => { }; /** @typedef {ReturnType} IdMap */ +/** @deprecated */ export const storageHelper = { /** @param { string } txt */ parseCapData: txt => { @@ -185,6 +187,7 @@ export const storageHelper = { harden(storageHelper); /** + * @deprecated * @param {IdMap} ctx * @param {VStorage} vstorage * @returns {Promise} From b141ce6e47ede661ff4e6777390665238c0e1f00 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Wed, 6 Nov 2024 10:33:25 -0800 Subject: [PATCH 15/19] feat: one marshaller per WalletUtils --- packages/client-utils/src/wallet-utils.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/client-utils/src/wallet-utils.js b/packages/client-utils/src/wallet-utils.js index 9ad670093d8..9d4dfa72df5 100644 --- a/packages/client-utils/src/wallet-utils.js +++ b/packages/client-utils/src/wallet-utils.js @@ -9,6 +9,7 @@ import { boardSlottingMarshaller, makeRpcUtils } from './rpc.js'; export const makeWalletUtils = async ({ fetch, delay }, networkConfig) => { const { agoricNames, fromBoard, marshaller, readLatestHead, vstorage } = await makeRpcUtils({ fetch }, networkConfig); + const m = boardSlottingMarshaller(fromBoard.convertSlotToVal); const client = await makeStargateClient(networkConfig); @@ -17,8 +18,6 @@ export const makeWalletUtils = async ({ fetch, delay }, networkConfig) => { * @param {number|string} [minHeight] */ const storedWalletState = async (from, minHeight = undefined) => { - const m = boardSlottingMarshaller(fromBoard.convertSlotToVal); - const history = await vstorage.readFully( `published.wallet.${from}`, minHeight, From 085db85a4d167f66d391417a1753b3f0d469d5ea Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Wed, 6 Nov 2024 10:35:43 -0800 Subject: [PATCH 16/19] chore(types): more annotations --- packages/agoric-cli/src/commands/inter.js | 2 +- packages/client-utils/src/wallet-utils.js | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/agoric-cli/src/commands/inter.js b/packages/agoric-cli/src/commands/inter.js index 2db02720deb..ac70eca77a9 100644 --- a/packages/agoric-cli/src/commands/inter.js +++ b/packages/agoric-cli/src/commands/inter.js @@ -329,7 +329,7 @@ inter auction status * @param {string} from * @param {import('@agoric/smart-wallet/src/offers.js').OfferSpec} offer * @param {Awaited>} tools - * @param {boolean?} dryRun + * @param {boolean | undefined} dryRun */ const placeBid = async (from, offer, tools, dryRun = false) => { const { networkConfig, agoricNames, pollOffer } = tools; diff --git a/packages/client-utils/src/wallet-utils.js b/packages/client-utils/src/wallet-utils.js index 9d4dfa72df5..b218456e7be 100644 --- a/packages/client-utils/src/wallet-utils.js +++ b/packages/client-utils/src/wallet-utils.js @@ -4,8 +4,16 @@ import { boardSlottingMarshaller, makeRpcUtils } from './rpc.js'; /** * @import {Amount, Brand} from '@agoric/ertp/src/types.js' + * @import {MinimalNetworkConfig} from './rpc.js'; */ +/** + * + * @param {object} root0 + * @param {typeof globalThis.fetch} root0.fetch + * @param {(ms: number) => Promise} root0.delay + * @param {MinimalNetworkConfig} networkConfig + */ export const makeWalletUtils = async ({ fetch, delay }, networkConfig) => { const { agoricNames, fromBoard, marshaller, readLatestHead, vstorage } = await makeRpcUtils({ fetch }, networkConfig); From 129516a8f3ae58f16d17460f58d2c69ee215a584 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Wed, 6 Nov 2024 10:52:24 -0800 Subject: [PATCH 17/19] feat: makeTendermintRpcClient --- packages/casting/src/main.js | 1 + packages/casting/src/makeHttpClient.js | 5 ++++- packages/casting/test/interpose-net-access.test.js | 6 +++--- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/casting/src/main.js b/packages/casting/src/main.js index 6b0eee6ec01..f8fa0cb2f37 100644 --- a/packages/casting/src/main.js +++ b/packages/casting/src/main.js @@ -11,3 +11,4 @@ export * from './follower-cosmjs.js'; export * from './casting-spec.js'; export * from './leader.js'; export * from './iterable.js'; +export * from './makeHttpClient.js'; diff --git a/packages/casting/src/makeHttpClient.js b/packages/casting/src/makeHttpClient.js index e6fe7c1ec7e..a8fbd77b38b 100644 --- a/packages/casting/src/makeHttpClient.js +++ b/packages/casting/src/makeHttpClient.js @@ -25,7 +25,7 @@ const filterBadStatus = res => { * @param {typeof window.fetch} fetch * @returns {import('@cosmjs/tendermint-rpc').RpcClient} */ -export const makeHttpClient = (url, fetch) => { +export const makeTendermintRpcClient = (url, fetch) => { const headers = {}; // XXX needed? // based on cosmjs 0.30.1: @@ -54,3 +54,6 @@ export const makeHttpClient = (url, fetch) => { }, }); }; + +/** @deprecated use makeTendermintRpcClient */ +export const makeHttpClient = makeTendermintRpcClient; diff --git a/packages/casting/test/interpose-net-access.test.js b/packages/casting/test/interpose-net-access.test.js index f0a0110d32d..87913ff3461 100644 --- a/packages/casting/test/interpose-net-access.test.js +++ b/packages/casting/test/interpose-net-access.test.js @@ -12,7 +12,7 @@ import { QueryChildrenResponse, } from '@agoric/cosmic-proto/vstorage/query.js'; -import { makeHttpClient } from '../src/makeHttpClient.js'; +import { makeTendermintRpcClient } from '../src/makeHttpClient.js'; import { captureIO, replayIO, web1, web2 } from './net-access-fixture.js'; /** @type {import('ava').TestFn>>} */ @@ -43,7 +43,7 @@ const scenario1 = { test('interpose net access', async t => { const fetchMock = replayIO(web1); - const rpcClient = makeHttpClient(scenario1.endpoint, fetchMock); + const rpcClient = makeTendermintRpcClient(scenario1.endpoint, fetchMock); t.log('raw JSON RPC'); const res = await rpcClient.execute({ @@ -100,7 +100,7 @@ test(`vstorage query: Children (RECORDING: ${RECORDING})`, async t => { const { fetch: fetchMock, web } = io.recording ? captureIO(io.fetch) : { fetch: replayIO(web2), web: new Map() }; - const rpcClient = makeHttpClient(scenario2.endpoint, fetchMock); + const rpcClient = makeTendermintRpcClient(scenario2.endpoint, fetchMock); const tmClient = await Tendermint34Client.create(rpcClient); const qClient = new QueryClient(tmClient); From c8f7407903078acaccb3a97f9ff722d92e51eee8 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Wed, 6 Nov 2024 10:52:42 -0800 Subject: [PATCH 18/19] feat: ocap makeStargateClient --- packages/client-utils/package.json | 2 ++ packages/client-utils/src/chain.js | 10 +++++++--- packages/client-utils/src/rpc.js | 12 ++++++++++++ packages/client-utils/src/wallet-utils.js | 2 +- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/packages/client-utils/package.json b/packages/client-utils/package.json index 455c85e6ab6..56470dd9c2e 100644 --- a/packages/client-utils/package.json +++ b/packages/client-utils/package.json @@ -26,11 +26,13 @@ "ts-blank-space": "^0.4.1" }, "dependencies": { + "@agoric/casting": "^0.4.2", "@agoric/ertp": "^0.16.2", "@agoric/internal": "^0.3.2", "@agoric/smart-wallet": "^0.5.3", "@agoric/vats": "^0.15.1", "@cosmjs/stargate": "^0.32.3", + "@cosmjs/tendermint-rpc": "^0.32.3", "@endo/common": "^1.2.7", "@endo/errors": "^1.2.7", "@endo/marshal": "^1.6.1", diff --git a/packages/client-utils/src/chain.js b/packages/client-utils/src/chain.js index 4cfa4bcb620..b42314a63f3 100644 --- a/packages/client-utils/src/chain.js +++ b/packages/client-utils/src/chain.js @@ -3,14 +3,18 @@ */ import { StargateClient } from '@cosmjs/stargate'; -import { pickEndpoint } from './rpc.js'; +import { makeTendermint34Client, pickEndpoint } from './rpc.js'; /** * @param {MinimalNetworkConfig} config + * @param {{ fetch: typeof window.fetch }} io * @returns {Promise} */ -export const makeStargateClient = config => - StargateClient.connect(pickEndpoint(config)); +export const makeStargateClient = async (config, { fetch }) => { + const url = pickEndpoint(config); + const tm = await makeTendermint34Client(url, { fetch }); + return StargateClient.create(tm); +}; /** * @param {{ diff --git a/packages/client-utils/src/rpc.js b/packages/client-utils/src/rpc.js index cf8121f3856..64df53ecee6 100644 --- a/packages/client-utils/src/rpc.js +++ b/packages/client-utils/src/rpc.js @@ -3,6 +3,8 @@ import { boardSlottingMarshaller, makeBoardRemote, } from '@agoric/vats/tools/board-utils.js'; +import { makeTendermintRpcClient } from '@agoric/casting'; +import { Tendermint34Client } from '@cosmjs/tendermint-rpc'; export { boardSlottingMarshaller }; @@ -246,3 +248,13 @@ export const makeRpcUtils = async ({ fetch }, config) => { } }; /** @typedef {Awaited>} RpcUtils */ + +/** + * @param {string} endpoint + * @param {{ fetch: typeof window.fetch }} io + * @returns {Promise} + */ +export const makeTendermint34Client = (endpoint, { fetch }) => { + const rpcClient = makeTendermintRpcClient(endpoint, fetch); + return Tendermint34Client.create(rpcClient); +}; diff --git a/packages/client-utils/src/wallet-utils.js b/packages/client-utils/src/wallet-utils.js index b218456e7be..151291fbc54 100644 --- a/packages/client-utils/src/wallet-utils.js +++ b/packages/client-utils/src/wallet-utils.js @@ -19,7 +19,7 @@ export const makeWalletUtils = async ({ fetch, delay }, networkConfig) => { await makeRpcUtils({ fetch }, networkConfig); const m = boardSlottingMarshaller(fromBoard.convertSlotToVal); - const client = await makeStargateClient(networkConfig); + const client = await makeStargateClient(networkConfig, { fetch }); /** * @param {string} from From c3f5438038ee7841ff4ea065a17befd697cf6601 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Tue, 5 Nov 2024 17:33:39 -0800 Subject: [PATCH 19/19] test: exports list --- packages/client-utils/package.json | 2 +- packages/client-utils/test/exports.test.js | 10 +++++++++ .../test/snapshots/exports.test.js.md | 20 ++++++++++++++++++ .../test/snapshots/exports.test.js.snap | Bin 0 -> 326 bytes 4 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 packages/client-utils/test/exports.test.js create mode 100644 packages/client-utils/test/snapshots/exports.test.js.md create mode 100644 packages/client-utils/test/snapshots/exports.test.js.snap diff --git a/packages/client-utils/package.json b/packages/client-utils/package.json index 56470dd9c2e..65c393fe954 100644 --- a/packages/client-utils/package.json +++ b/packages/client-utils/package.json @@ -53,7 +53,7 @@ "--no-warnings" ], "require": [ - "@endo/init/debug.js" + "@endo/init/legacy.js" ], "timeout": "20m" } diff --git a/packages/client-utils/test/exports.test.js b/packages/client-utils/test/exports.test.js new file mode 100644 index 00000000000..50e17472bf3 --- /dev/null +++ b/packages/client-utils/test/exports.test.js @@ -0,0 +1,10 @@ +/* eslint-disable import/no-extraneous-dependencies -- requiring the package itself to check exports map */ +// @ts-check + +import test from 'ava'; + +import * as index from '@agoric/client-utils'; + +test('index', t => { + t.snapshot(Object.keys(index).sort()); +}); diff --git a/packages/client-utils/test/snapshots/exports.test.js.md b/packages/client-utils/test/snapshots/exports.test.js.md new file mode 100644 index 00000000000..4c9278c387d --- /dev/null +++ b/packages/client-utils/test/snapshots/exports.test.js.md @@ -0,0 +1,20 @@ +# Snapshot report for `test/exports.test.js` + +The actual snapshot is saved in `exports.test.js.snap`. + +Generated by [AVA](https://avajs.dev). + +## index + +> Snapshot 1 + + [ + 'boardSlottingMarshaller', + 'makeAgoricNames', + 'makeFromBoard', + 'makeRpcUtils', + 'makeVStorage', + 'makeWalletUtils', + 'pickEndpoint', + 'storageHelper', + ] diff --git a/packages/client-utils/test/snapshots/exports.test.js.snap b/packages/client-utils/test/snapshots/exports.test.js.snap new file mode 100644 index 0000000000000000000000000000000000000000..69755e0fad0b6c1a04051ce3c08a50c4958bb754 GIT binary patch literal 326 zcmV-M0lEG`RzVJ0MZ%9LC^q)sti0Z} zcDDdTlXFmoV{j6VgBDmLPc_ne^UciWX{k(Jx%CHo=@qlo1wTutMdMb+yY;3hgclF= zmSBKTG^EibfH{Cy0Pg@k0et;H;DCT*0v-vNQh!3}%v$k66uT_TKqJsLXpAZKuuBOj zozVW$2wNJPvr? z({o&E6lB|97(oV|V!W%0}j-1NWPI!Kz{V4Kji3