Comparing version
{ | ||
"name": "agoric", | ||
"version": "0.21.2-dev-75cc4e2.0+75cc4e2", | ||
"version": "0.21.2-dev-75e8d38.0+75e8d38", | ||
"description": "Manage the Agoric Javascript smart contract platform", | ||
@@ -13,3 +13,4 @@ "type": "module", | ||
"./src/entrypoint.js": "./src/entrypoint.js", | ||
"./src/helpers.js": "./src/helpers.js" | ||
"./src/helpers.js": "./src/helpers.js", | ||
"./src/lib/index.js": "./src/lib/index.js" | ||
}, | ||
@@ -24,3 +25,3 @@ "files": [ | ||
"test": "ava", | ||
"test:c8": "c8 $C8_OPTIONS ava --config=ava-nesm.config.js", | ||
"test:c8": "c8 --all $C8_OPTIONS ava", | ||
"test:xs": "exit 0", | ||
@@ -34,46 +35,45 @@ "integration-test": "ava --config .ava-integration-test.config.js", | ||
"devDependencies": { | ||
"@agoric/cosmic-swingset": "0.41.4-dev-75cc4e2.0+75cc4e2", | ||
"@agoric/deploy-script-support": "0.10.4-dev-75cc4e2.0+75cc4e2", | ||
"@agoric/cosmic-swingset": "0.41.4-dev-75e8d38.0+75e8d38", | ||
"@agoric/deploy-script-support": "0.10.4-dev-75e8d38.0+75e8d38", | ||
"ava": "^5.3.0", | ||
"c8": "^9.1.0", | ||
"dd-trace": "^4.11.1" | ||
"c8": "^10.1.2" | ||
}, | ||
"dependencies": { | ||
"@agoric/access-token": "0.4.22-dev-75cc4e2.0+75cc4e2", | ||
"@agoric/cache": "0.3.3-dev-75cc4e2.0+75cc4e2", | ||
"@agoric/casting": "0.4.3-dev-75cc4e2.0+75cc4e2", | ||
"@agoric/cosmic-proto": "0.4.1-dev-75cc4e2.0+75cc4e2", | ||
"@agoric/ertp": "0.16.3-dev-75cc4e2.0+75cc4e2", | ||
"@agoric/governance": "0.10.4-dev-75cc4e2.0+75cc4e2", | ||
"@agoric/inter-protocol": "0.16.2-dev-75cc4e2.0+75cc4e2", | ||
"@agoric/internal": "0.3.3-dev-75cc4e2.0+75cc4e2", | ||
"@agoric/network": "0.1.1-dev-75cc4e2.0+75cc4e2", | ||
"@agoric/smart-wallet": "0.5.4-dev-75cc4e2.0+75cc4e2", | ||
"@agoric/store": "0.9.3-dev-75cc4e2.0+75cc4e2", | ||
"@agoric/swingset-vat": "0.32.3-dev-75cc4e2.0+75cc4e2", | ||
"@agoric/vats": "0.15.2-dev-75cc4e2.0+75cc4e2", | ||
"@agoric/zoe": "0.26.3-dev-75cc4e2.0+75cc4e2", | ||
"@agoric/zone": "0.2.3-dev-75cc4e2.0+75cc4e2", | ||
"@confio/relayer": "^0.11.3", | ||
"@cosmjs/crypto": "^0.32.3", | ||
"@cosmjs/encoding": "^0.32.3", | ||
"@cosmjs/math": "^0.32.3", | ||
"@cosmjs/proto-signing": "^0.32.3", | ||
"@cosmjs/stargate": "^0.32.3", | ||
"@endo/bundle-source": "^3.4.0", | ||
"@endo/captp": "^4.3.0", | ||
"@endo/compartment-mapper": "^1.2.2", | ||
"@endo/env-options": "^1.1.6", | ||
"@endo/errors": "^1.2.5", | ||
"@endo/far": "^1.1.5", | ||
"@endo/init": "^1.1.4", | ||
"@endo/marshal": "^1.5.3", | ||
"@endo/nat": "^5.0.10", | ||
"@endo/patterns": "^1.4.3", | ||
"@endo/promise-kit": "^1.1.5", | ||
"@endo/zip": "^1.0.7", | ||
"@agoric/access-token": "0.4.22-dev-75e8d38.0+75e8d38", | ||
"@agoric/cache": "0.3.3-dev-75e8d38.0+75e8d38", | ||
"@agoric/casting": "0.4.3-dev-75e8d38.0+75e8d38", | ||
"@agoric/client-utils": "0.1.1-dev-75e8d38.0+75e8d38", | ||
"@agoric/cosmic-proto": "0.4.1-dev-75e8d38.0+75e8d38", | ||
"@agoric/ertp": "0.16.3-dev-75e8d38.0+75e8d38", | ||
"@agoric/governance": "0.10.4-dev-75e8d38.0+75e8d38", | ||
"@agoric/inter-protocol": "0.16.2-dev-75e8d38.0+75e8d38", | ||
"@agoric/internal": "0.3.3-dev-75e8d38.0+75e8d38", | ||
"@agoric/network": "0.1.1-dev-75e8d38.0+75e8d38", | ||
"@agoric/smart-wallet": "0.5.4-dev-75e8d38.0+75e8d38", | ||
"@agoric/store": "0.9.3-dev-75e8d38.0+75e8d38", | ||
"@agoric/swingset-vat": "0.32.3-dev-75e8d38.0+75e8d38", | ||
"@agoric/vats": "0.15.2-dev-75e8d38.0+75e8d38", | ||
"@agoric/zoe": "0.26.3-dev-75e8d38.0+75e8d38", | ||
"@agoric/zone": "0.2.3-dev-75e8d38.0+75e8d38", | ||
"@cosmjs/crypto": "^0.33.0", | ||
"@cosmjs/encoding": "^0.33.0", | ||
"@cosmjs/math": "^0.33.0", | ||
"@cosmjs/proto-signing": "^0.33.0", | ||
"@cosmjs/stargate": "^0.33.0", | ||
"@endo/bundle-source": "^3.5.1", | ||
"@endo/captp": "^4.4.4", | ||
"@endo/compartment-mapper": "^1.5.0", | ||
"@endo/env-options": "^1.1.8", | ||
"@endo/errors": "^1.2.9", | ||
"@endo/far": "^1.1.10", | ||
"@endo/init": "^1.1.8", | ||
"@endo/marshal": "^1.6.3", | ||
"@endo/nat": "^5.0.14", | ||
"@endo/patterns": "^1.4.8", | ||
"@endo/promise-kit": "^1.1.9", | ||
"@endo/zip": "^1.0.9", | ||
"@iarna/toml": "^2.2.3", | ||
"anylogger": "^0.21.0", | ||
"chalk": "^5.2.0", | ||
"commander": "^11.1.0", | ||
"commander": "^12.1.0", | ||
"deterministic-json": "^1.0.5", | ||
@@ -105,5 +105,5 @@ "esm": "agoric-labs/esm#Agoric-built", | ||
"typeCoverage": { | ||
"atLeast": 77.44 | ||
"atLeast": 78.96 | ||
}, | ||
"gitHead": "75cc4e26530875f8d625722f3bd372dca656fa38" | ||
"gitHead": "75e8d388b2e48420f325aae6978d047cf7fe4d33" | ||
} |
@@ -5,75 +5,2 @@ # Agoric CLI | ||
## Relaying via IBC | ||
The CLI integrates support for the [Confio | ||
ts-relayer](https://github.com/confio/ts-relayer#quick-start) via the | ||
`agoric ibc-setup` and `agoric ibc-relayer` commands. | ||
Run `agoric start --reset -v local-chain` in a project directory. In the | ||
meantime, you can configure the relayer (note that `--registry-from .` means to use `./registry.yaml`): | ||
```console | ||
$ agoric ibc-setup init --registry-from . --src local --dest ollinet | ||
... | ||
$ agoric ibc-setup keys list | ||
ollinet: agoric1fwk40de0xu7gtlk8z858q2f5lfcqv33ml8qdg4 | ||
local: agoric1rvyry6jqmcrrm4ay9tu23rer7que8kdj4206zk | ||
$ | ||
``` | ||
Once your chain has booted, send some `uist` tokens to your `local` relayer | ||
account printed above: | ||
```console | ||
$ agd --home=_agstate/keys tx --keyring-backend=test bank send provision agoric1rvyry6jqmcrrm4ay9tu23rer7que8kdj4206zk 20000000uist --from=provision --chain-id=agoriclocal --yes | ||
... | ||
$ | ||
``` | ||
Go to https://ollinet.faucet.agoric.net and fund your `ollinet` relayer account | ||
printed above with BLD/IBC toy tokens. | ||
Check your relayer balances. Both `local` and `ollinet` relayer accounts should | ||
show `ubld` and `uist`: | ||
```console | ||
$ agoric ibc-setup balances | ||
CHAIN AMOUNT | ||
ollinet 74972124ubld | ||
local 20000000uist | ||
$ | ||
``` | ||
Create an ICS-20 fungible token transfer channel: | ||
```console | ||
$ agoric ibc-setup ics20 -v | ||
... | ||
Created channel: | ||
agoriclocal: transfer/channel-0 (connection-0) | ||
agoricollinet-55: transfer/channel-33 (connection-12) | ||
$ | ||
``` | ||
Now that the channel exists, you can relay packets along it just by using: | ||
```console | ||
$ agoric ibc-relayer start -v --poll 15 | ||
``` | ||
Leave this running in the background, and use the above `transfer/channel-0` or | ||
`transfer/channel-33` to send tokens back and forth. The following | ||
example uses the `tx ibc-transfer transfer` command, and then | ||
`transfer channel-0` to indicate the `transfer/channel-0` portID/channelID. It really wants you to know this is about token *transfer*. | ||
```console | ||
$ agd --home=_agstate/keys tx ibc-transfer transfer --keyring-backend=test \ | ||
transfer channel-0 \ | ||
agoric1fwk40de0xu7gtlk8z858q2f5lfcqv33ml8qdg4 200uist \ | ||
--from=provision --chain-id=agoriclocal --yes | ||
... | ||
# Watch the ibc-relayer send a packet and its acknowledgement, then... | ||
$ agd query bank balances agoric1rvyry6jqmcrrm4ay9tu23rer7que8kdj4206zk | ||
``` | ||
## Developing Agoric CLI | ||
@@ -80,0 +7,0 @@ |
@@ -31,4 +31,4 @@ /* eslint-env node */ | ||
const oldExt = anylogger.ext; | ||
anylogger.ext = (l, o) => { | ||
l = oldExt(l, o); | ||
anylogger.ext = (l, ...rest) => { | ||
l = oldExt(l, ...rest); | ||
l.enabledFor = lvl => globalCode >= anylogger.levels[lvl]; | ||
@@ -35,0 +35,0 @@ |
@@ -33,3 +33,2 @@ #!/usr/bin/env node | ||
program.addCommand(makeOracleCommand(logger)); | ||
program.addCommand(makeGovCommand(logger)); | ||
@@ -73,2 +72,3 @@ program.addCommand(makePerfCommand(logger)); | ||
program.addCommand(makeOracleCommand(procIO, logger)); | ||
program.addCommand(makeReserveCommand(logger, procIO)); | ||
@@ -75,0 +75,0 @@ program.addCommand(makeAuctionCommand(logger, { ...procIO, fetch })); |
@@ -84,3 +84,8 @@ import djson from 'deterministic-json'; | ||
// Rewrite the app.toml. | ||
/** | ||
* Rewrite the app.toml. | ||
* | ||
* @param {{ appToml: string, enableCors?: boolean, exportMetrics?: boolean, portNum?: string, chainId?: string, enableRosetta?: boolean, rosettaPort?: string }} input | ||
* @returns {string} toml | ||
*/ | ||
export function finishCosmosApp({ | ||
@@ -96,2 +101,4 @@ appToml, | ||
const rpcPort = Number(portNum); | ||
// TODO: Use an accurate narrow type. | ||
/** @type {Record<string, any>} */ | ||
const app = TOML.parse(appToml); | ||
@@ -143,3 +150,8 @@ | ||
// Rewrite the config.toml. | ||
/** | ||
* Rewrite the config.toml. | ||
* | ||
* @param {{ configToml: string, enableCors?: boolean, exportMetrics?: boolean, portNum?: string, persistentPeers?: string, seeds?: string, unconditionalPeerIds?: string }} input | ||
* @returns {string} toml | ||
*/ | ||
export function finishTendermintConfig({ | ||
@@ -157,2 +169,4 @@ configToml, | ||
// Adjust the config.toml. | ||
// TODO: Use an accurate narrow type. | ||
/** @type {Record<string, any>} */ | ||
const config = TOML.parse(configToml); | ||
@@ -196,3 +210,8 @@ | ||
// Rewrite/import the genesis.json. | ||
/** | ||
* Rewrite/import the genesis.json. | ||
* | ||
* @param {{ genesisJson: string, exportedGenesisJson?: string }} input | ||
* @returns {string} json | ||
*/ | ||
export function finishCosmosGenesis({ genesisJson, exportedGenesisJson }) { | ||
@@ -199,0 +218,0 @@ const genesis = JSON.parse(genesisJson); |
// @ts-check | ||
/* eslint-env node */ | ||
import { | ||
fetchEnvNetworkConfig, | ||
makeAgoricNames, | ||
makeVstorageKit, | ||
} from '@agoric/client-utils'; | ||
import { Fail } from '@endo/errors'; | ||
import { InvalidArgumentError } from 'commander'; | ||
import { Fail } from '@endo/errors'; | ||
import { makeRpcUtils } from '../lib/rpc.js'; | ||
import { outputActionAndHint } from '../lib/wallet.js'; | ||
@@ -13,2 +17,4 @@ | ||
const networkConfig = await fetchEnvNetworkConfig({ env: process.env, fetch }); | ||
/** | ||
@@ -63,7 +69,2 @@ * @template {ParamTypesMap} M | ||
) | ||
.option( | ||
'--discount-step <integer>', | ||
'proposed value (basis points)', | ||
BigInt, | ||
) | ||
.requiredOption( | ||
@@ -96,10 +97,10 @@ '--charterAcceptOfferId <string>', | ||
async opts => { | ||
const { agoricNames, readLatestHead } = await makeRpcUtils({ fetch }); | ||
/** @type {{ current: AuctionParamRecord }} */ | ||
// @ts-expect-error XXX should runtime check? | ||
const { current } = await readLatestHead( | ||
`published.auction.governance`, | ||
const { readPublished, ...vsk } = makeVstorageKit( | ||
{ fetch }, | ||
networkConfig, | ||
); | ||
const agoricNames = await makeAgoricNames(vsk.fromBoard, vsk.vstorage); | ||
const { current } = await readPublished(`auction.governance`); | ||
const { | ||
@@ -106,0 +107,0 @@ AuctionStartDelay: { |
// @ts-check | ||
/* eslint-disable func-names */ | ||
/* global globalThis, process, setTimeout */ | ||
/* eslint-env node */ | ||
import { | ||
fetchEnvNetworkConfig, | ||
makeAgoricNames, | ||
makeVstorageKit, | ||
} 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 '../lib/rpc.js'; | ||
import { | ||
@@ -17,4 +21,6 @@ findContinuingIds, | ||
/** | ||
* @import {OfferSpec} from '@agoric/smart-wallet/src/offers.js' | ||
* @import {QuestionDetails} from '@agoric/governance/src/types.js' | ||
* @import {OfferSpec} from '@agoric/smart-wallet/src/offers.js'; | ||
* @import {AgoricNamesRemotes} from '@agoric/vats/tools/board-utils.js'; | ||
* @import {CurrentWalletRecord} from '@agoric/smart-wallet/src/smartWallet.js'; | ||
* @import {VstorageKit} from '@agoric/client-utils'; | ||
*/ | ||
@@ -29,2 +35,4 @@ | ||
const networkConfig = await fetchEnvNetworkConfig({ env: process.env, fetch }); | ||
/** | ||
@@ -45,6 +53,5 @@ * @param {import('anylogger').Logger} _logger | ||
// default to conventional ambient IO facilities. | ||
env = process.env, | ||
stdout = process.stdout, | ||
stderr = process.stderr, | ||
fetch = globalThis.fetch, | ||
fetch = global.fetch, | ||
execFileSync = execFileSyncAmbient, | ||
@@ -90,3 +97,3 @@ delay = ms => new Promise(resolve => setTimeout(resolve, ms)), | ||
* @param {{ | ||
* toOffer: (agoricNames: *, current: import('@agoric/smart-wallet/src/smartWallet.js').CurrentWalletRecord | undefined) => OfferSpec, | ||
* toOffer: (agoricNames: AgoricNamesRemotes, current: CurrentWalletRecord | undefined) => OfferSpec, | ||
* sendFrom?: string | undefined, | ||
@@ -96,11 +103,12 @@ * keyringBackend: string, | ||
* }} detail | ||
* @param {Awaited<ReturnType<makeRpcUtils>>} [optUtils] | ||
* @param {VstorageKit} [vsk] | ||
*/ | ||
const processOffer = async function ( | ||
{ toOffer, sendFrom, keyringBackend }, | ||
optUtils, | ||
vsk, | ||
) { | ||
const networkConfig = await getNetworkConfig(env); | ||
const utils = await (optUtils || makeRpcUtils({ fetch })); | ||
const { agoricNames, readLatestHead } = utils; | ||
await null; | ||
vsk ||= makeVstorageKit({ fetch }, networkConfig); | ||
const { readPublished } = vsk; | ||
const agoricNames = await makeAgoricNames(vsk.fromBoard, vsk.vstorage); | ||
@@ -111,3 +119,3 @@ assert(keyringBackend, 'missing keyring-backend option'); | ||
if (sendFrom) { | ||
current = await getCurrent(sendFrom, { readLatestHead }); | ||
current = await getCurrent(sendFrom, { readPublished }); | ||
} | ||
@@ -142,5 +150,5 @@ | ||
const [state, update] = await Promise.all([ | ||
getCurrent(sendFrom, { readLatestHead }), | ||
getLastUpdate(sendFrom, { readLatestHead }), | ||
readLatestHead(`published.wallet.${sendFrom}`), | ||
getCurrent(sendFrom, { readPublished }), | ||
getLastUpdate(sendFrom, { readPublished }), | ||
readPublished(`wallet.${sendFrom}`), | ||
]); | ||
@@ -274,4 +282,8 @@ if (update.updated === 'offerStatus' && update.status.id === offer.id) { | ||
.action(async opts => { | ||
const { agoricNames, readLatestHead } = await makeRpcUtils({ fetch }); | ||
const current = await getCurrent(opts.from, { readLatestHead }); | ||
const { readPublished, ...vsk } = makeVstorageKit( | ||
{ fetch }, | ||
networkConfig, | ||
); | ||
const agoricNames = await makeAgoricNames(vsk.fromBoard, vsk.vstorage); | ||
const current = await getCurrent(opts.from, { readPublished }); | ||
@@ -301,4 +313,8 @@ const known = findContinuingIds(current, agoricNames); | ||
.action(async opts => { | ||
const { agoricNames, readLatestHead } = await makeRpcUtils({ fetch }); | ||
const current = await getCurrent(opts.from, { readLatestHead }); | ||
const { readPublished, ...vsk } = makeVstorageKit( | ||
{ fetch }, | ||
networkConfig, | ||
); | ||
const agoricNames = await makeAgoricNames(vsk.fromBoard, vsk.vstorage); | ||
const current = await getCurrent(opts.from, { readPublished }); | ||
@@ -338,7 +354,7 @@ const found = findContinuingIds(current, agoricNames); | ||
.action(async function (opts, options) { | ||
const utils = await makeRpcUtils({ fetch }); | ||
const { readLatestHead } = utils; | ||
const vsk = makeVstorageKit({ fetch }, networkConfig); | ||
const { readPublished } = vsk; | ||
const info = await readLatestHead( | ||
`published.committees.${opts.pathname}.latestQuestion`, | ||
const questionDesc = await readPublished( | ||
`committees.${opts.pathname}.latestQuestion`, | ||
).catch(err => { | ||
@@ -350,5 +366,2 @@ // CommanderError is a class constructor, and so | ||
// XXX runtime shape-check | ||
const questionDesc = /** @type {QuestionDetails} */ (info); | ||
// TODO support multiple position arguments | ||
@@ -394,3 +407,3 @@ const chosenPositions = [questionDesc.positions[opts.forPosition]]; | ||
}, | ||
utils, | ||
vsk, | ||
); | ||
@@ -397,0 +410,0 @@ }); |
@@ -7,9 +7,8 @@ /** | ||
// @ts-check | ||
import { CommanderError, InvalidArgumentError } from 'commander'; | ||
// TODO: should get M from endo https://github.com/Agoric/agoric-sdk/issues/7090 | ||
import { fetchEnvNetworkConfig, 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'; | ||
import { M, matches } from '@agoric/store'; | ||
import { M, matches } from '@endo/patterns'; | ||
import { CommanderError, InvalidArgumentError } from 'commander'; | ||
import { normalizeAddressWithOptions, pollBlocks } from '../lib/chain.js'; | ||
@@ -21,9 +20,3 @@ import { | ||
} from '../lib/format.js'; | ||
import { getNetworkConfig } from '../lib/rpc.js'; | ||
import { | ||
getCurrent, | ||
makeWalletUtils, | ||
outputActionAndHint, | ||
sendAction, | ||
} from '../lib/wallet.js'; | ||
import { getCurrent, outputActionAndHint, sendAction } from '../lib/wallet.js'; | ||
@@ -243,4 +236,4 @@ const { values } = Object; | ||
// await null above makes this await safe | ||
const networkConfig = await getNetworkConfig(env); | ||
return makeWalletUtils({ fetch, execFileSync, delay }, networkConfig); | ||
const networkConfig = await fetchEnvNetworkConfig({ env, fetch }); | ||
return makeWalletUtils({ fetch, delay }, networkConfig); | ||
} catch (err) { | ||
@@ -293,10 +286,8 @@ // CommanderError is a class constructor, and so | ||
) => { | ||
const { agoricNames, readLatestHead } = await tryMakeUtils(); | ||
const { agoricNames, readPublished } = await tryMakeUtils(); | ||
/** @type { [ScheduleNotification, BookDataNotification, *] } */ | ||
// @ts-expect-error dynamic cast | ||
const [schedule, book, { current: params }] = await Promise.all([ | ||
readLatestHead(`published.auction.schedule`), | ||
readLatestHead(`published.auction.book${opts.book}`), | ||
readLatestHead(`published.auction.governance`), | ||
readPublished('auction.schedule'), | ||
readPublished(`auction.book${opts.book}`), | ||
readPublished('auction.governance'), | ||
]); | ||
@@ -341,3 +332,3 @@ | ||
* @param {Awaited<ReturnType<tryMakeUtils>>} tools | ||
* @param {boolean?} dryRun | ||
* @param {boolean | undefined} dryRun | ||
*/ | ||
@@ -507,5 +498,5 @@ const placeBid = async (from, offer, tools, dryRun = false) => { | ||
const { networkConfig, readLatestHead } = await tryMakeUtils(); | ||
const { networkConfig, readPublished } = await tryMakeUtils(); | ||
const current = await getCurrent(from, { readLatestHead }); | ||
const current = await getCurrent(from, { readPublished }); | ||
const liveIds = current.liveOffers.map(([i, _s]) => i); | ||
@@ -535,3 +526,3 @@ if (!liveIds.includes(id)) { | ||
const checkGone = async blockInfo => { | ||
const pollResult = await getCurrent(from, { readLatestHead }); | ||
const pollResult = await getCurrent(from, { readPublished }); | ||
const found = pollResult.liveOffers.find(([i, _]) => i === id); | ||
@@ -578,7 +569,7 @@ if (found) throw Error('retry'); | ||
async opts => { | ||
const { agoricNames, readLatestHead, storedWalletState } = | ||
const { agoricNames, readPublished, storedWalletState } = | ||
await tryMakeUtils(); | ||
const [current, state] = await Promise.all([ | ||
getCurrent(opts.from, { readLatestHead }), | ||
getCurrent(opts.from, { readPublished }), | ||
storedWalletState(opts.from), | ||
@@ -585,0 +576,0 @@ ]); |
// @ts-check | ||
/* eslint-disable func-names */ | ||
/* eslint-env node */ | ||
import { | ||
fetchEnvNetworkConfig, | ||
makeAgoricNames, | ||
makeVstorageKit, | ||
makeWalletUtils, | ||
storageHelper, | ||
} from '@agoric/client-utils'; | ||
import { Offers } from '@agoric/inter-protocol/src/clientSupport.js'; | ||
@@ -8,3 +15,2 @@ import { oracleBrandFeedName } from '@agoric/inter-protocol/src/proposals/utils.js'; | ||
import { Nat } from '@endo/nat'; | ||
import * as cp from 'child_process'; | ||
import { Command } from 'commander'; | ||
@@ -14,6 +20,4 @@ import { inspect } from 'util'; | ||
import { bigintReplacer } from '../lib/format.js'; | ||
import { getNetworkConfig, makeRpcUtils, storageHelper } from '../lib/rpc.js'; | ||
import { | ||
getCurrent, | ||
makeWalletUtils, | ||
outputAction, | ||
@@ -28,3 +32,4 @@ sendAction, | ||
const COSMOS_UNIT = 1_000_000n; | ||
const scaleDecimals = num => BigInt(num * Number(COSMOS_UNIT)); | ||
/** @param {number} num */ | ||
const scaleDecimals = num => BigInt(Math.round(num * Number(COSMOS_UNIT))); | ||
@@ -34,17 +39,23 @@ /** | ||
* | ||
* @param {import('anylogger').Logger} logger | ||
* @param {{ | ||
* delay?: (ms: number) => Promise<void>, | ||
* execFileSync?: typeof import('child_process').execFileSync, | ||
* env?: Record<string, string | undefined>, | ||
* stdout?: Pick<import('stream').Writable,'write'>, | ||
* }} [io] | ||
* createCommand: typeof import('commander').createCommand, | ||
* env: Partial<Record<string, string>>, | ||
* execFileSync: typeof import('child_process').execFileSync, | ||
* now: () => number, | ||
* setTimeout: typeof setTimeout, | ||
* stderr: Pick<import('stream').Writable,'write'>, | ||
* stdout: Pick<import('stream').Writable,'write'>, | ||
* }} process | ||
* @param {import('anylogger').Logger} [logger] | ||
*/ | ||
export const makeOracleCommand = (logger, io = {}) => { | ||
const { | ||
delay = ms => new Promise(resolve => setTimeout(resolve, ms)), | ||
execFileSync = cp.execFileSync, | ||
env = process.env, | ||
stdout = process.stdout, | ||
} = io; | ||
export const makeOracleCommand = ( | ||
{ env, execFileSync, setTimeout, stderr, stdout }, | ||
logger, | ||
) => { | ||
/** | ||
* @param {number} ms | ||
* @returns {Promise<void>} | ||
*/ | ||
const delay = ms => new Promise(resolve => setTimeout(resolve, ms)); | ||
const oracle = new Command('oracle') | ||
@@ -89,10 +100,14 @@ .description('Oracle commands') | ||
// XXX pass fetch to getNetworkConfig() explicitly | ||
const networkConfig = await getNetworkConfig(env); | ||
const utils = await makeRpcUtils({ fetch }); | ||
const networkConfig = await fetchEnvNetworkConfig({ | ||
env: process.env, | ||
fetch, | ||
}); | ||
const vsk = makeVstorageKit({ fetch }, networkConfig); | ||
const agoricNames = await makeAgoricNames(vsk.fromBoard, vsk.vstorage); | ||
const lookupPriceAggregatorInstance = ([brandIn, brandOut]) => { | ||
const name = oracleBrandFeedName(brandIn, brandOut); | ||
const instance = utils.agoricNames.instance[name]; | ||
const instance = agoricNames.instance[name]; | ||
if (!instance) { | ||
logger.debug('known instances:', utils.agoricNames.instance); | ||
logger && logger.debug('known instances:', agoricNames.instance); | ||
throw Error(`Unknown instance ${name}`); | ||
@@ -103,3 +118,3 @@ } | ||
return { ...utils, networkConfig, lookupPriceAggregatorInstance }; | ||
return { ...vsk, networkConfig, lookupPriceAggregatorInstance }; | ||
}; | ||
@@ -137,8 +152,11 @@ | ||
outputAction({ | ||
method: 'executeOffer', | ||
offer, | ||
}); | ||
outputAction( | ||
{ | ||
method: 'executeOffer', | ||
offer, | ||
}, | ||
stdout, | ||
); | ||
console.warn(sendHint); | ||
stderr.write(sendHint); | ||
}); | ||
@@ -173,12 +191,15 @@ | ||
outputAction({ | ||
method: 'executeOffer', | ||
offer, | ||
}); | ||
outputAction( | ||
{ | ||
method: 'executeOffer', | ||
offer, | ||
}, | ||
stdout, | ||
); | ||
console.warn(sendHint); | ||
stderr.write(sendHint); | ||
}); | ||
const findOracleCap = async (instance, from, readLatestHead) => { | ||
const current = await getCurrent(from, { readLatestHead }); | ||
const findOracleCap = async (instance, from, readPublished) => { | ||
const current = await getCurrent(from, { readPublished }); | ||
@@ -211,7 +232,6 @@ const { offerToUsedInvitation: entries } = /** @type {any} */ (current); | ||
.action(async opts => { | ||
const { readLatestHead, lookupPriceAggregatorInstance } = | ||
await rpcTools(); | ||
const { readPublished, lookupPriceAggregatorInstance } = await rpcTools(); | ||
const instance = lookupPriceAggregatorInstance(opts.pair); | ||
const offerId = await findOracleCap(instance, opts.from, readLatestHead); | ||
const offerId = await findOracleCap(instance, opts.from, readPublished); | ||
if (!offerId) { | ||
@@ -277,8 +297,9 @@ console.error('No continuing ids found'); | ||
) => { | ||
const { readLatestHead, networkConfig, lookupPriceAggregatorInstance } = | ||
await rpcTools(); | ||
const wutil = await makeWalletUtils( | ||
{ fetch, execFileSync, delay }, | ||
const { | ||
readLatestHead, | ||
readPublished, | ||
networkConfig, | ||
); | ||
lookupPriceAggregatorInstance, | ||
} = await rpcTools(); | ||
const wutil = await makeWalletUtils({ fetch, delay }, networkConfig); | ||
const unitPrice = scaleDecimals(price); | ||
@@ -292,3 +313,3 @@ | ||
const viewer = `https://vstorage.agoric.net/#${networkConfig.rpcAddrs[0]}|published,published.priceFeed|${feedPath}`; | ||
console.warn(`no existing price data; see ${viewer}`); | ||
stderr.write(`no existing price data; see ${viewer}`); | ||
return undefined; | ||
@@ -338,3 +359,3 @@ }) | ||
]).catch(err => { | ||
console.warn(err); | ||
stderr.write(err); | ||
}); | ||
@@ -349,3 +370,3 @@ } | ||
from, | ||
readLatestHead, | ||
readPublished, | ||
); | ||
@@ -352,0 +373,0 @@ if (!adminOfferIds[from]) { |
@@ -10,7 +10,8 @@ // @ts-check | ||
} from '@agoric/casting'; | ||
import { fetchEnvNetworkConfig } from '@agoric/client-utils'; | ||
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 { slotToRemotable } from '@agoric/internal/src/storage-test-utils.js'; | ||
import { boardSlottingMarshaller } from '@agoric/vats/tools/board-utils.js'; | ||
import { makeLeaderOptions } from '../lib/casting.js'; | ||
@@ -21,3 +22,2 @@ import { | ||
} from '../lib/chain.js'; | ||
import { networkConfig } from '../lib/rpc.js'; | ||
@@ -27,2 +27,4 @@ // tight for perf testing but less than this tends to hang. | ||
const networkConfig = await fetchEnvNetworkConfig({ env: process.env, fetch }); | ||
/** | ||
@@ -29,0 +31,0 @@ * @param {import('anylogger').Logger} logger |
// @ts-check | ||
/* eslint-disable func-names */ | ||
/* eslint-env node */ | ||
import { | ||
fetchEnvNetworkConfig, | ||
makeAgoricNames, | ||
makeVstorageKit, | ||
storageHelper, | ||
} from '@agoric/client-utils'; | ||
import { Offers } from '@agoric/inter-protocol/src/clientSupport.js'; | ||
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 { outputExecuteOfferAction } from '../lib/wallet.js'; | ||
const networkConfig = await fetchEnvNetworkConfig({ env: process.env, fetch }); | ||
// Adapted from https://gist.github.com/dckc/8b5b2f16395cb4d7f2ff340e0bc6b610#file-psm-tool | ||
@@ -63,9 +70,10 @@ | ||
const rpcTools = async () => { | ||
const utils = await makeRpcUtils({ fetch }); | ||
const vsk = await makeVstorageKit({ fetch }, networkConfig); | ||
const agoricNames = await makeAgoricNames(vsk.fromBoard, vsk.vstorage); | ||
const lookupPsmInstance = ([minted, anchor]) => { | ||
const name = `psm-${minted}-${anchor}`; | ||
const instance = utils.agoricNames.instance[name]; | ||
const instance = agoricNames.instance[name]; | ||
if (!instance) { | ||
logger.debug('known instances:', utils.agoricNames.instance); | ||
logger.debug('known instances:', agoricNames.instance); | ||
throw Error(`Unknown instance ${name}`); | ||
@@ -81,3 +89,3 @@ } | ||
const getGovernanceState = async ([Minted, Anchor]) => { | ||
const govContent = await utils.vstorage.readLatest( | ||
const govContent = await vsk.vstorage.readLatest( | ||
`published.psm.${Minted}.${Anchor}.governance`, | ||
@@ -87,6 +95,5 @@ ); | ||
const { current: governance } = last( | ||
storageHelper.unserializeTxt(govContent, utils.fromBoard), | ||
storageHelper.unserializeTxt(govContent, vsk.fromBoard), | ||
); | ||
const { [`psm.${Minted}.${Anchor}`]: instance } = | ||
utils.agoricNames.instance; | ||
const { [`psm.${Minted}.${Anchor}`]: instance } = agoricNames.instance; | ||
@@ -96,3 +103,3 @@ return { instance, governance }; | ||
return { ...utils, lookupPsmInstance, getGovernanceState }; | ||
return { ...vsk, agoricNames, lookupPsmInstance, getGovernanceState }; | ||
}; | ||
@@ -99,0 +106,0 @@ |
// @ts-check | ||
/* eslint-disable func-names */ | ||
/* eslint-env node */ | ||
import { | ||
fetchEnvNetworkConfig, | ||
makeAgoricNames, | ||
makeVstorageKit, | ||
} from '@agoric/client-utils'; | ||
import { Offers } from '@agoric/inter-protocol/src/clientSupport.js'; | ||
import { Command } from 'commander'; | ||
import { makeRpcUtils } from '../lib/rpc.js'; | ||
import { outputActionAndHint } from '../lib/wallet.js'; | ||
const networkConfig = await fetchEnvNetworkConfig({ env: process.env, fetch }); | ||
/** | ||
@@ -32,3 +38,4 @@ * @param {import('anylogger').Logger} _logger | ||
async ({ collateralBrand, ...opts }) => { | ||
const { agoricNames } = await makeRpcUtils({ fetch }); | ||
const vsk = makeVstorageKit({ fetch }, networkConfig); | ||
const agoricNames = await makeAgoricNames(vsk.fromBoard, vsk.vstorage); | ||
@@ -67,3 +74,4 @@ const offer = Offers.reserve.AddCollateral(agoricNames, { | ||
.action(async function (opts) { | ||
const { agoricNames } = await makeRpcUtils({ fetch }); | ||
const vsk = makeVstorageKit({ fetch }, networkConfig); | ||
const agoricNames = await makeAgoricNames(vsk.fromBoard, vsk.vstorage); | ||
@@ -70,0 +78,0 @@ const reserveInstance = agoricNames.instance.reserve; |
// @ts-check | ||
/* eslint-env node */ | ||
import { fetchEnvNetworkConfig, makeWalletUtils } from '@agoric/client-utils'; | ||
import { Fail } from '@endo/errors'; | ||
@@ -7,4 +8,3 @@ import { CommanderError } from 'commander'; | ||
import { bigintReplacer } from '../lib/format.js'; | ||
import { getNetworkConfig } from '../lib/rpc.js'; | ||
import { makeWalletUtils, sendAction } from '../lib/wallet.js'; | ||
import { sendAction } from '../lib/wallet.js'; | ||
@@ -42,4 +42,4 @@ /** | ||
// await null above makes this await safe | ||
const networkConfig = await getNetworkConfig(env); | ||
return makeWalletUtils({ fetch, execFileSync, delay }, networkConfig); | ||
const networkConfig = await fetchEnvNetworkConfig({ env, fetch }); | ||
return makeWalletUtils({ fetch, delay }, networkConfig); | ||
} catch (err) { | ||
@@ -46,0 +46,0 @@ // CommanderError is a class constructor, and so |
// @ts-check | ||
/* eslint-disable func-names */ | ||
/* eslint-env node */ | ||
import { Command } from 'commander'; | ||
import { | ||
fetchEnvNetworkConfig, | ||
makeAgoricNames, | ||
makeVstorageKit, | ||
} 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 '../lib/rpc.js'; | ||
import { getCurrent, outputExecuteOfferAction } from '../lib/wallet.js'; | ||
const networkConfig = await fetchEnvNetworkConfig({ env: process.env, fetch }); | ||
/** | ||
@@ -39,6 +45,6 @@ * @param {import('anylogger').Logger} logger | ||
.action(async function (opts) { | ||
const { readLatestHead } = await makeRpcUtils({ fetch }); | ||
const { readPublished } = await makeVstorageKit({ fetch }, networkConfig); | ||
const current = await getCurrent(opts.from, { | ||
readLatestHead, | ||
readPublished, | ||
}); | ||
@@ -65,3 +71,4 @@ | ||
logger.warn('running with options', opts); | ||
const { agoricNames } = await makeRpcUtils({ fetch }); | ||
const vsk = makeVstorageKit({ fetch }, networkConfig); | ||
const agoricNames = await makeAgoricNames(vsk.fromBoard, vsk.vstorage); | ||
@@ -101,7 +108,11 @@ const offer = Offers.vaults.OpenVault(agoricNames, { | ||
logger.warn('running with options', opts); | ||
const { agoricNames, readLatestHead } = await makeRpcUtils({ fetch }); | ||
const { readPublished, ...vsk } = makeVstorageKit( | ||
{ fetch }, | ||
networkConfig, | ||
); | ||
const agoricNames = await makeAgoricNames(vsk.fromBoard, vsk.vstorage); | ||
const previousOfferId = await lookupOfferIdForVault( | ||
opts.vaultId, | ||
getCurrent(opts.from, { readLatestHead }), | ||
getCurrent(opts.from, { readPublished }), | ||
); | ||
@@ -143,7 +154,11 @@ | ||
logger.warn('running with options', opts); | ||
const { agoricNames, readLatestHead } = await makeRpcUtils({ fetch }); | ||
const { readPublished, ...vsk } = makeVstorageKit( | ||
{ fetch }, | ||
networkConfig, | ||
); | ||
const agoricNames = await makeAgoricNames(vsk.fromBoard, vsk.vstorage); | ||
const previousOfferId = await lookupOfferIdForVault( | ||
opts.vaultId, | ||
getCurrent(opts.from, { readLatestHead }), | ||
getCurrent(opts.from, { readPublished }), | ||
); | ||
@@ -150,0 +165,0 @@ |
@@ -11,7 +11,10 @@ // @ts-check | ||
} from '@agoric/casting'; | ||
import { | ||
makeVstorageKit, | ||
fetchEnvNetworkConfig, | ||
makeAgoricNames, | ||
} 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 '../lib/format.js'; | ||
import { makeRpcUtils, networkConfig } from '../lib/rpc.js'; | ||
@@ -24,4 +27,11 @@ import { makeLeaderOptions } from '../lib/casting.js'; | ||
} from '../lib/chain.js'; | ||
import { | ||
fmtRecordOfLines, | ||
parseFiniteNumber, | ||
summarize, | ||
} from '../lib/format.js'; | ||
import { coalesceWalletState, getCurrent } from '../lib/wallet.js'; | ||
const networkConfig = await fetchEnvNetworkConfig({ env: process.env, fetch }); | ||
const SLEEP_SECONDS = 3; | ||
@@ -50,2 +60,3 @@ | ||
/** @param {string} literalOrName */ | ||
const normalizeAddress = literalOrName => | ||
@@ -108,5 +119,5 @@ normalizeAddressWithOptions(literalOrName, wallet.opts()); | ||
const { unserializer } = await makeRpcUtils({ fetch }); | ||
const { marshaller } = makeVstorageKit({ fetch }, networkConfig); | ||
const offerObj = unserializer.fromCapData(JSON.parse(offerStr)); | ||
const offerObj = marshaller.fromCapData(JSON.parse(offerStr)); | ||
console.log(offerObj); | ||
@@ -124,5 +135,5 @@ }); | ||
const { unserializer } = await makeRpcUtils({ fetch }); | ||
const { marshaller } = makeVstorageKit({ fetch }, networkConfig); | ||
const offerObj = unserializer.fromCapData(JSON.parse(offerStr)); | ||
const offerObj = marshaller.fromCapData(JSON.parse(offerStr)); | ||
console.log(offerObj.offer.id); | ||
@@ -140,9 +151,27 @@ }); | ||
.option('--dry-run', 'spit out the command instead of running it') | ||
.option('--gas', 'gas limit; "auto" [default] to calculate automatically') | ||
.option( | ||
'--gas-adjustment', | ||
'factor by which to multiply the --gas=auto calculation result [default 1.2]', | ||
) | ||
.option('--verbose', 'print command output') | ||
.action(function (opts) { | ||
/** @typedef {{ from: string, offer: string, dryRun: boolean }} Opts */ | ||
/** | ||
* @typedef {{ | ||
* from: string, | ||
* offer: string, | ||
* dryRun: boolean, | ||
* gas: string, | ||
* gasAdjustment: string, | ||
* verbose: boolean, | ||
* }} Opts | ||
*/ | ||
const { | ||
dryRun, | ||
from, | ||
gas = 'auto', | ||
gasAdjustment = '1.2', | ||
offer, | ||
home, | ||
verbose, | ||
keyringBackend: backend, | ||
@@ -152,8 +181,29 @@ } = /** @type {SharedTxOptions & Opts} */ ({ ...wallet.opts(), ...opts }); | ||
const offerBody = fs.readFileSync(offer).toString(); | ||
execSwingsetTransaction(['wallet-action', '--allow-spend', offerBody], { | ||
from, | ||
dryRun, | ||
keyring: { home, backend }, | ||
...networkConfig, | ||
}); | ||
const out = execSwingsetTransaction( | ||
['wallet-action', '--allow-spend', offerBody, '-ojson', '-bblock'], | ||
{ | ||
...networkConfig, | ||
keyring: { home, backend }, | ||
from, | ||
gas: | ||
gas === 'auto' | ||
? ['auto', parseFiniteNumber(gasAdjustment)] | ||
: parseFiniteNumber(gas), | ||
dryRun, | ||
verbose, | ||
}, | ||
); | ||
// see sendAction in {@link ../lib/wallet.js} | ||
if (dryRun || !verbose) return; | ||
try { | ||
const tx = JSON.parse(/** @type {string} */ (out)); | ||
if (tx.code !== 0) { | ||
console.error('failed to send tx', tx); | ||
} | ||
console.log(tx); | ||
} catch (err) { | ||
console.error('unexpected output', JSON.stringify(out)); | ||
throw err; | ||
} | ||
}); | ||
@@ -165,3 +215,3 @@ | ||
.action(async function () { | ||
const { vstorage } = await makeRpcUtils({ fetch }); | ||
const { vstorage } = makeVstorageKit({ fetch }, networkConfig); | ||
const wallets = await vstorage.keys('published.wallet'); | ||
@@ -180,5 +230,8 @@ process.stdout.write(wallets.join('\n')); | ||
.action(async function (opts) { | ||
const { agoricNames, unserializer, readLatestHead } = await makeRpcUtils({ | ||
fetch, | ||
}); | ||
const { | ||
readPublished, | ||
marshaller: unserializer, | ||
...vsk | ||
} = makeVstorageKit({ fetch }, networkConfig); | ||
const agoricNames = await makeAgoricNames(vsk.fromBoard, vsk.vstorage); | ||
@@ -190,3 +243,3 @@ const leader = makeLeader(networkConfig.rpcAddrs[0]); | ||
{ | ||
// @ts-expect-error xxx | ||
// @ts-expect-error xxx follower/marshaller types | ||
unserializer, | ||
@@ -198,3 +251,3 @@ }, | ||
const current = await getCurrent(opts.from, { readLatestHead }); | ||
const current = await getCurrent(opts.from, { readPublished }); | ||
@@ -201,0 +254,0 @@ console.warn( |
@@ -53,3 +53,3 @@ import chalk from 'chalk'; | ||
// Ensure the build doesn't mess up stdout. | ||
ps.childProcess.stdout.pipe(process.stderr); | ||
ps.childProcess.stdout?.pipe(process.stderr); | ||
return ps; | ||
@@ -56,0 +56,0 @@ } |
@@ -6,2 +6,5 @@ /* eslint-env node */ | ||
// Backwards compatibility | ||
export { fetchEnvNetworkConfig as getNetworkConfig } from '@agoric/client-utils'; | ||
export const getSDKBinaries = ({ | ||
@@ -44,8 +47,8 @@ jsPfx = '../..', | ||
* @param {Array<string>} cargs arguments to the command | ||
* @param {object} param2 | ||
* @param {string} [param2.cwd] | ||
* @param {string | [string, string, string]} [param2.stdio] standard IO | ||
* @param {object} [opts] | ||
* @param {string} [opts.cwd] | ||
* @param {string | [string, string, string]} [opts.stdio] standard IO | ||
* specification | ||
* @param {Record<string, string | undefined>} [param2.env] environment | ||
* @param {boolean} [param2.detached] whether the child process should be detached | ||
* @param {Record<string, string | undefined>} [opts.env] environment | ||
* @param {boolean} [opts.detached] whether the child process should be detached | ||
* @returns {Promise<number> & { childProcess: ChildProcess }}} promise for | ||
@@ -52,0 +55,0 @@ * exit status. The return result has a `childProcess` property to obtain |
/* eslint-env node */ | ||
import path from 'path'; | ||
import chalk from 'chalk'; | ||
import { execFileSync } from 'child_process'; | ||
import { makePspawn } from './helpers.js'; | ||
import DEFAULT_SDK_PACKAGE_NAMES from './sdk-package-names.js'; | ||
import { listWorkspaces } from './lib/packageManager.js'; | ||
@@ -33,13 +35,3 @@ const REQUIRED_AGORIC_START_PACKAGES = [ | ||
async function getWorktreePackagePaths(cwd = '.', map = new Map()) { | ||
// run `yarn workspaces info` to get the list of directories to | ||
// use, instead of a hard-coded list | ||
const p = pspawn('yarn', ['workspaces', '--silent', 'info'], { | ||
cwd, | ||
stdio: ['inherit', 'pipe', 'inherit'], | ||
}); | ||
const stdout = []; | ||
p.childProcess.stdout.on('data', out => stdout.push(out)); | ||
await p; | ||
const d = JSON.parse(Buffer.concat(stdout).toString('utf-8')); | ||
for (const [name, { location }] of Object.entries(d)) { | ||
for (const { name, location } of listWorkspaces({ execFileSync }, cwd)) { | ||
map.set(name, path.resolve(cwd, location)); | ||
@@ -53,3 +45,3 @@ } | ||
let sdkWorktree; | ||
/** @type {Map<string, string>} */ | ||
/** @type {Map<string, string | null>} */ | ||
const sdkPackageToPath = new Map(); | ||
@@ -136,3 +128,2 @@ const linkFolder = path.resolve(`_agstate/yarn-links`); | ||
// Don't update on exit anymore. | ||
// eslint-disable-next-line no-use-before-define | ||
process.off('beforeExit', updatePackageJsonOnExit); | ||
@@ -176,3 +167,3 @@ log.info(`updating ${pjson}`); | ||
const failures = results.filter( | ||
({ status }) => status !== 'fulfilled', | ||
result => result.status !== 'fulfilled', | ||
); | ||
@@ -291,2 +282,6 @@ if (failures.length) { | ||
[...sdkPackageToPath.entries()].map(async ([pjName, dir]) => { | ||
if (typeof dir !== 'string') { | ||
throw Error(`unexpected incomplete package mapping: ${pjName}`); | ||
} | ||
const SUBOPTIMAL = false; | ||
@@ -309,3 +304,3 @@ await null; | ||
.mkdir(linkDir, { recursive: true }) | ||
.then(_ => fs.symlink(path.relative(linkDir, dir), linkName)); | ||
.then(() => fs.symlink(path.relative(linkDir, dir), linkName)); | ||
}), | ||
@@ -312,0 +307,0 @@ ); |
@@ -6,2 +6,7 @@ // @ts-check | ||
/** | ||
* @import {MinimalNetworkConfig} from '@agoric/client-utils'; | ||
* @import {ParamsSDKType} from '@agoric/cosmic-proto/agoric/swingset/swingset.js'; | ||
*/ | ||
const agdBinary = 'agd'; | ||
@@ -38,7 +43,38 @@ | ||
/** @typedef {number | 'auto' | ['auto', adjustment?: number | undefined]} GasLimit */ | ||
/** | ||
* @param {GasLimit} limit | ||
* @returns {string[]} | ||
*/ | ||
const makeGasOpts = limit => { | ||
if (Number.isFinite(limit) || limit === 'auto') { | ||
return [`--gas=${limit}`]; | ||
} | ||
if (Array.isArray(limit) && limit.length >= 1 && limit[0] === 'auto') { | ||
const gasOpts = ['--gas=auto']; | ||
if (limit.length > 1) { | ||
const [adjustment, ...rest] = limit.slice(1); | ||
const adjustmentIsValid = | ||
adjustment === undefined || | ||
(Number.isFinite(adjustment) && Number(adjustment) > 0); | ||
if (rest.length !== 0 || !adjustmentIsValid) { | ||
throw Error('invalid gas input'); | ||
} | ||
if (adjustment !== undefined) { | ||
gasOpts.push(`--gas-adjustment=${adjustment}`); | ||
} | ||
} | ||
return gasOpts; | ||
} | ||
throw Error('invalid gas input'); | ||
}; | ||
/** | ||
* @param {ReadonlyArray<string>} swingsetArgs | ||
* @param {import('./rpc.js').MinimalNetworkConfig & { | ||
* @param {MinimalNetworkConfig & { | ||
* from: string, | ||
* fees?: string, | ||
* gas?: GasLimit, | ||
* dryRun?: boolean, | ||
@@ -55,2 +91,3 @@ * verbose?: boolean, | ||
fees, | ||
gas = ['auto', 1.2], | ||
dryRun = false, | ||
@@ -73,2 +110,3 @@ verbose = true, | ||
feeOpt, | ||
makeGasOpts(gas), | ||
[`--from=${from}`, 'tx', 'swingset'], | ||
@@ -85,3 +123,3 @@ swingsetArgs, | ||
const yesCmd = cmd.concat(['--yes']); | ||
if (verbose) console.log('Executing ', yesCmd); | ||
if (verbose) console.log('Executing ', agdBinary, yesCmd); | ||
const out = execFileSync(agdBinary, yesCmd, { encoding: 'utf-8' }); | ||
@@ -102,3 +140,4 @@ | ||
* | ||
* @param {import('./rpc.js').MinimalNetworkConfig} net | ||
* @param {MinimalNetworkConfig} net | ||
* @returns {ParamsSDKType} | ||
*/ | ||
@@ -123,3 +162,3 @@ // TODO fetch by HTTP instead of shelling out https://github.com/Agoric/agoric-sdk/issues/9200 | ||
/** | ||
* @param {import('./rpc.js').MinimalNetworkConfig & { | ||
* @param {MinimalNetworkConfig & { | ||
* execFileSync: typeof import('child_process').execFileSync, | ||
@@ -164,3 +203,3 @@ * delay: (ms: number) => Promise<void>, | ||
* @param {string} txhash | ||
* @param {import('./rpc.js').MinimalNetworkConfig & { | ||
* @param {MinimalNetworkConfig & { | ||
* execFileSync: typeof import('child_process').execFileSync, | ||
@@ -188,3 +227,3 @@ * delay: (ms: number) => Promise<void>, | ||
], | ||
{ stdio: ['ignore', 'pipe', 'ignore'] }, | ||
{ stdio: ['ignore', 'pipe', 'pipe'] }, | ||
); | ||
@@ -191,0 +230,0 @@ // XXX this type is defined in a .proto file somewhere |
@@ -1,21 +0,19 @@ | ||
// @ts-check | ||
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'; | ||
*/ | ||
// TODO Move to packages/internal. | ||
/** | ||
* Like @endo/nat but coerces | ||
* Parses the input and returns either a finite number or NaN. | ||
* | ||
* @param {string} str | ||
* @returns {bigint} | ||
* @param {string} input | ||
* @returns {number} | ||
*/ | ||
export const Natural = str => { | ||
const b = BigInt(str); | ||
if (b < 0) { | ||
throw RangeError(`${b} is negative`); | ||
} | ||
return b; | ||
export const parseFiniteNumber = input => { | ||
const result = /[0-9]/.test(input || '') ? Number(input) : NaN; | ||
return Number.isFinite(result) ? result : NaN; | ||
}; | ||
@@ -105,2 +103,3 @@ | ||
const { stringify } = JSON; | ||
/** @type {Array<[string, string[]]>} */ | ||
const groups = Object.entries(record).map(([key, items]) => [ | ||
@@ -110,6 +109,6 @@ key, | ||
]); | ||
const lineEntries = groups.map( | ||
// @ts-expect-error ??? | ||
([key, lines]) => ` ${stringify(key)}: [\n${lines.join(',\n')}\n ]`, | ||
); | ||
const lineEntries = groups.map(([key, lines]) => { | ||
const linesStr = lines.length === 0 ? `[]` : `[\n${lines.join(',\n')}\n ]`; | ||
return ` ${stringify(key)}: ${linesStr}`; | ||
}); | ||
return `{\n${lineEntries.join(',\n')}\n}`; | ||
@@ -122,3 +121,3 @@ }; | ||
* @param {import('@agoric/smart-wallet/src/utils.js').CoalescedWalletState} state | ||
* @param {import('@agoric/vats/tools/board-utils.js').AgoricNamesRemotes} agoricNames | ||
* @param {AgoricNamesRemotes} agoricNames | ||
*/ | ||
@@ -180,3 +179,3 @@ export const offerStatusTuples = (state, agoricNames) => { | ||
* @param {ReturnType<import('@agoric/smart-wallet/src/utils.js').makeWalletStateCoalescer>['state']} coalesced | ||
* @param {import('@agoric/vats/tools/board-utils.js').AgoricNamesRemotes} agoricNames | ||
* @param {AgoricNamesRemotes} agoricNames | ||
*/ | ||
@@ -183,0 +182,0 @@ export const summarize = (current, coalesced, agoricNames) => { |
// @ts-check | ||
/* eslint-env node */ | ||
import { Fail } from '@endo/errors'; | ||
import { iterateReverse } from '@agoric/casting'; | ||
import { boardSlottingMarshaller } from '@agoric/client-utils'; | ||
import { makeWalletStateCoalescer } from '@agoric/smart-wallet/src/utils.js'; | ||
import { execSwingsetTransaction, pollBlocks, pollTx } from './chain.js'; | ||
import { boardSlottingMarshaller, makeRpcUtils } from './rpc.js'; | ||
import { Fail } from '@endo/errors'; | ||
import { execSwingsetTransaction, 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, VstorageKit} from '@agoric/client-utils'; | ||
*/ | ||
@@ -25,6 +28,6 @@ const marshaller = boardSlottingMarshaller(); | ||
* @param {string} addr | ||
* @param {Pick<import('./rpc.js').RpcUtils, 'readLatestHead'>} io | ||
* @param {Pick<VstorageKit, 'readPublished'>} io | ||
* @returns {Promise<import('@agoric/smart-wallet/src/smartWallet.js').CurrentWalletRecord>} | ||
*/ | ||
export const getCurrent = async (addr, { readLatestHead }) => { | ||
export const getCurrent = async (addr, { readPublished }) => { | ||
// Partial because older writes may not have had all properties | ||
@@ -34,3 +37,3 @@ // NB: assumes changes are only additions | ||
/** @type {Partial<import('@agoric/smart-wallet/src/smartWallet.js').CurrentWalletRecord> | undefined} */ ( | ||
await readLatestHead(`published.wallet.${addr}.current`) | ||
await readPublished(`wallet.${addr}.current`) | ||
); | ||
@@ -62,8 +65,7 @@ if (current === undefined) { | ||
* @param {string} addr | ||
* @param {Pick<import('./rpc.js').RpcUtils, 'readLatestHead'>} io | ||
* @param {Pick<VstorageKit, 'readPublished'>} io | ||
* @returns {Promise<import('@agoric/smart-wallet/src/smartWallet.js').UpdateRecord>} | ||
*/ | ||
export const getLastUpdate = (addr, { readLatestHead }) => { | ||
// @ts-expect-error cast | ||
return readLatestHead(`published.wallet.${addr}`); | ||
export const getLastUpdate = (addr, { readPublished }) => { | ||
return readPublished(`wallet.${addr}`); | ||
}; | ||
@@ -148,3 +150,3 @@ | ||
* @param {import('@agoric/smart-wallet/src/smartWallet.js').BridgeAction} bridgeAction | ||
* @param {import('./rpc.js').MinimalNetworkConfig & { | ||
* @param {MinimalNetworkConfig & { | ||
* from: string, | ||
@@ -154,3 +156,3 @@ * fees?: string, | ||
* keyring?: {home?: string, backend: string}, | ||
* stdout: Pick<import('stream').Writable, 'write'>, | ||
* stdout?: Pick<import('stream').Writable, 'write'>, | ||
* execFileSync: typeof import('child_process').execFileSync, | ||
@@ -219,74 +221,1 @@ * delay: (ms: number) => Promise<void>, | ||
}; | ||
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, | ||
}; | ||
}; |
@@ -69,3 +69,5 @@ /* eslint-env node */ | ||
); | ||
const baseCmd = (...args) => addCmdOpts(program.command(...args)); | ||
/** @type {typeof program.command} */ | ||
const baseCmd = (nameAndParams, ...rest) => | ||
addCmdOpts(program.command(nameAndParams, ...rest)); | ||
@@ -89,15 +91,2 @@ addCmdOpts( | ||
const ibcSetup = path.join( | ||
dirname, | ||
'..', | ||
'node_modules', | ||
'.bin', | ||
'ibc-setup', | ||
); | ||
program.command( | ||
'ibc-setup <command...>', | ||
'set up Inter Blockchain Communication', | ||
{ executableFile: ibcSetup }, | ||
); | ||
baseCmd('open') | ||
@@ -187,17 +176,2 @@ .description('launch the Agoric UI') | ||
const ibcRelayer = path.join( | ||
dirname, | ||
'..', | ||
'node_modules', | ||
'.bin', | ||
'ibc-relayer', | ||
); | ||
program.command( | ||
'ibc-relayer', | ||
'run an Inter Blockchain Communications relayer', | ||
{ | ||
executableFile: ibcRelayer, | ||
}, | ||
); | ||
baseCmd('install [force-sdk-version]') | ||
@@ -214,13 +188,9 @@ .description('install Dapp dependencies') | ||
.option( | ||
'--proof <strict | optimistic | none>', | ||
'set proof mode', | ||
'--proof <none>', | ||
`set proof mode (currently only 'none' is supported)`, | ||
value => { | ||
assert( | ||
['strict', 'optimistic', 'none'].includes(value), | ||
X`--proof must be one of 'strict', 'optimistic', or 'none'`, | ||
TypeError, | ||
); | ||
assert.equal(value, 'none', X`--proof can only be 'none'`, TypeError); | ||
return value; | ||
}, | ||
'optimistic', | ||
'none', | ||
) | ||
@@ -227,0 +197,0 @@ .option( |
@@ -59,3 +59,3 @@ // @ts-check | ||
* @param {string[]} scripts | ||
* @param {{ allowUnsafePlugins: boolean, progname: string, rawArgs: string[], endowments?: Record<string, any> }} opts | ||
* @param {{ allowUnsafePlugins?: boolean, progname: string, rawArgs: string[], endowments?: Record<string, any> }} opts | ||
* @param {{ fs: import('fs/promises'), console: Console }} powers | ||
@@ -62,0 +62,0 @@ */ |
@@ -12,2 +12,3 @@ // DO NOT EDIT - automatically generated by get-sdk-package-names.js | ||
"@agoric/casting", | ||
"@agoric/client-utils", | ||
"@agoric/cosmic-proto", | ||
@@ -21,2 +22,3 @@ "@agoric/cosmic-swingset", | ||
"@agoric/eslint-config", | ||
"@agoric/fast-usdc", | ||
"@agoric/governance", | ||
@@ -23,0 +25,0 @@ "@agoric/import-manager", |
@@ -279,9 +279,9 @@ /* eslint-env node */ | ||
/** @type {(args: string[], spawnOpts?: Parameters<typeof pspawn>[2], dockerArgs?: string[]) => ReturnType<pspawn>} */ | ||
let chainSpawn; | ||
if (!popts.dockerTag) { | ||
chainSpawn = (args, spawnOpts = undefined) => { | ||
return pspawn(cosmosChain, [...args, `--home=${serverDir}`], spawnOpts); | ||
}; | ||
chainSpawn = (args, spawnOpts) => | ||
pspawn(cosmosChain, [...args, `--home=${serverDir}`], spawnOpts); | ||
} else { | ||
chainSpawn = (args, spawnOpts = undefined, dockerArgs = []) => | ||
chainSpawn = (args, spawnOpts, dockerArgs = []) => | ||
pspawn( | ||
@@ -486,8 +486,8 @@ 'docker', | ||
/** @type {(args: string[], spawnOpts?: Parameters<typeof pspawn>[2], dockerArgs?: string[]) => ReturnType<pspawn>} */ | ||
let soloSpawn; | ||
if (!popts.dockerTag) { | ||
soloSpawn = (args, spawnOpts = undefined) => | ||
pspawn(agSolo, args, spawnOpts); | ||
soloSpawn = (args, spawnOpts) => pspawn(agSolo, args, spawnOpts); | ||
} else { | ||
soloSpawn = (args, spawnOpts = undefined, dockerArgs = []) => | ||
soloSpawn = (args, spawnOpts, dockerArgs = []) => | ||
pspawn( | ||
@@ -494,0 +494,0 @@ 'docker', |
@@ -65,2 +65,9 @@ // @ts-check | ||
/** | ||
* Test the "getting started" workflow. Note that this function may be imported | ||
* by external repositories. | ||
* | ||
* @param {import('ava').ExecutionContext} t | ||
* @param {{ init?: string[], install?: string[] }} [options] | ||
*/ | ||
export const gettingStartedWorkflowTest = async (t, options = {}) => { | ||
@@ -176,3 +183,3 @@ const { init: initOptions = [], install: installOptions = [] } = options; | ||
// wait for the chain to start | ||
let lastKnownBlockHeight = 0n; | ||
let lastKnownBlockHeight = 2n; | ||
for (;;) { | ||
@@ -186,4 +193,4 @@ try { | ||
lastKnownBlockHeight = currentHeight; | ||
if (earlierHeight > 0n && currentHeight > earlierHeight) { | ||
// We've had at least one block produced. | ||
if (earlierHeight > 2n && currentHeight > earlierHeight) { | ||
// We've had at least 3 blocks produced. | ||
break; | ||
@@ -190,0 +197,0 @@ } |
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
4
-20%46
2.22%244358
-3.13%6907
-2.37%23
-76.04%37
19.35%44
18.92%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
Updated
Updated
Updated
Updated
Updated
Updated
Updated
Updated
Updated
Updated
Updated
Updated
Updated
Updated
Updated
Updated