Skip to content

Commit

Permalink
feat: client-utils package
Browse files Browse the repository at this point in the history
  • Loading branch information
turadg committed Nov 6, 2024
1 parent 769de1f commit 50af71f
Show file tree
Hide file tree
Showing 22 changed files with 141 additions and 21 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/test-all-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions packages/agoric-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion packages/agoric-cli/src/commands/auction.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/agoric-cli/src/commands/gov.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion packages/agoric-cli/src/commands/inter.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 5 additions & 1 deletion packages/agoric-cli/src/commands/oracle.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion packages/agoric-cli/src/commands/perf.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion packages/agoric-cli/src/commands/psm.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion packages/agoric-cli/src/commands/reserve.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/agoric-cli/src/commands/test-upgrade.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/agoric-cli/src/commands/vaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/agoric-cli/src/commands/wallet.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
12 changes: 8 additions & 4 deletions packages/agoric-cli/src/lib/chain.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';

/**
Expand Down Expand Up @@ -36,7 +40,7 @@ harden(normalizeAddressWithOptions);

/**
* @param {ReadonlyArray<string>} swingsetArgs
* @param {import('./rpc.js').MinimalNetworkConfig & {
* @param {MinimalNetworkConfig & {
* from: string,
* fees?: string,
* dryRun?: boolean,
Expand Down Expand Up @@ -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 => {
Expand All @@ -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<void>,
* period?: number,
Expand Down Expand Up @@ -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<void>,
* period?: number,
Expand Down
8 changes: 4 additions & 4 deletions packages/agoric-cli/src/lib/wallet.js
Original file line number Diff line number Diff line change
Expand Up @@ -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' */
Expand All @@ -22,7 +22,7 @@ const emptyCurrentRecord = {

/**
* @param {string} addr
* @param {Pick<import('./rpc.js').RpcUtils, 'readLatestHead'>} io
* @param {Pick<import('../../../client-utils/src/rpc.js').RpcUtils, 'readLatestHead'>} io
* @returns {Promise<import('@agoric/smart-wallet/src/smartWallet.js').CurrentWalletRecord>}
*/
export const getCurrent = async (addr, { readLatestHead }) => {
Expand Down Expand Up @@ -57,7 +57,7 @@ export const getCurrent = async (addr, { readLatestHead }) => {

/**
* @param {string} addr
* @param {Pick<import('./rpc.js').RpcUtils, 'readLatestHead'>} io
* @param {Pick<import('../../../client-utils/src/rpc.js').RpcUtils, 'readLatestHead'>} io
* @returns {Promise<import('@agoric/smart-wallet/src/smartWallet.js').UpdateRecord>}
*/
export const getLastUpdate = (addr, { readLatestHead }) => {
Expand Down Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions packages/agoric-cli/src/sdk-package-names.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export default [
"@agoric/builders",
"@agoric/cache",
"@agoric/casting",
"@agoric/client-utils",
"@agoric/cosmic-proto",
"@agoric/cosmic-swingset",
"@agoric/cosmos",
Expand Down
5 changes: 4 additions & 1 deletion packages/agoric-cli/test/inter-cli.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down
1 change: 1 addition & 0 deletions packages/client-utils/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Change Log
37 changes: 37 additions & 0 deletions packages/client-utils/README.md
Original file line number Diff line number Diff line change
@@ -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.

56 changes: 56 additions & 0 deletions packages/client-utils/package.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
1 change: 1 addition & 0 deletions packages/client-utils/src/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './rpc.js';
Original file line number Diff line number Diff line change
Expand Up @@ -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 =>
Expand All @@ -273,9 +273,9 @@ export const makeRpcUtils = async ({ fetch }, config = networkConfig) => {
return {
agoricNames,
fromBoard,
marshaller,
readLatestHead,
unserializeHead,
unserializer,
vstorage,
};
} catch (err) {
Expand Down
9 changes: 9 additions & 0 deletions packages/client-utils/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {},
"include": [
"scripts",
"src",
"test",
],
}

0 comments on commit 50af71f

Please sign in to comment.