From 2183c5e825e4cd47ddad25adc64d6ed89852983a Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Fri, 16 Jun 2023 10:31:39 -0700 Subject: [PATCH 1/8] refactor: OfferMaker takes agoricNames --- packages/agoric-cli/src/commands/psm.js | 2 +- packages/agoric-cli/src/commands/reserve.js | 2 +- packages/agoric-cli/src/commands/vaults.js | 6 +-- packages/inter-protocol/src/clientSupport.js | 50 ++++++++++--------- packages/smart-wallet/src/types.d.ts | 12 ++++- packages/vats/test/bootstrapTests/drivers.js | 8 +-- .../test/bootstrapTests/test-liquidation-1.js | 2 +- .../bootstrapTests/test-liquidation-2b.js | 2 +- 8 files changed, 48 insertions(+), 36 deletions(-) diff --git a/packages/agoric-cli/src/commands/psm.js b/packages/agoric-cli/src/commands/psm.js index e45dfe8ff9a..f28e4490e04 100644 --- a/packages/agoric-cli/src/commands/psm.js +++ b/packages/agoric-cli/src/commands/psm.js @@ -157,7 +157,7 @@ export const makePsmCommand = logger => { console.warn('running with options', opts); const { agoricNames, lookupPsmInstance } = await rpcTools(); const instance = await lookupPsmInstance(opts.pair); - const offer = Offers.psm.swap(instance, agoricNames.brand, opts); + const offer = Offers.psm.swap(agoricNames, instance, opts); outputExecuteOfferAction(offer); }); diff --git a/packages/agoric-cli/src/commands/reserve.js b/packages/agoric-cli/src/commands/reserve.js index 48adf0a7a1a..c064ec497f4 100644 --- a/packages/agoric-cli/src/commands/reserve.js +++ b/packages/agoric-cli/src/commands/reserve.js @@ -31,7 +31,7 @@ export const makeReserveCommand = (_logger, io = {}) => { async ({ collateralBrand, ...opts }) => { const { agoricNames } = await makeRpcUtils({ fetch }); - const offer = Offers.reserve.AddCollateral(agoricNames.brand, { + const offer = Offers.reserve.AddCollateral(agoricNames, { collateralBrandKey: collateralBrand, ...opts, }); diff --git a/packages/agoric-cli/src/commands/vaults.js b/packages/agoric-cli/src/commands/vaults.js index 27dac289098..284f613f9cd 100644 --- a/packages/agoric-cli/src/commands/vaults.js +++ b/packages/agoric-cli/src/commands/vaults.js @@ -63,7 +63,7 @@ export const makeVaultsCommand = logger => { logger.warn('running with options', opts); const { agoricNames } = await makeRpcUtils({ fetch }); - const offer = Offers.vaults.OpenVault(agoricNames.brand, { + const offer = Offers.vaults.OpenVault(agoricNames, { giveCollateral: opts.giveCollateral, wantMinted: opts.wantMinted, offerId: opts.offerId, @@ -104,7 +104,7 @@ export const makeVaultsCommand = logger => { ); const offer = Offers.vaults.AdjustBalances( - agoricNames.brand, + agoricNames, { giveCollateral: opts.giveCollateral, wantCollateral: opts.wantCollateral, @@ -145,7 +145,7 @@ export const makeVaultsCommand = logger => { ); const offer = Offers.vaults.CloseVault( - agoricNames.brand, + agoricNames, { giveMinted: opts.giveMinted, offerId: opts.offerId, diff --git a/packages/inter-protocol/src/clientSupport.js b/packages/inter-protocol/src/clientSupport.js index 49024f12646..204c5aee785 100644 --- a/packages/inter-protocol/src/clientSupport.js +++ b/packages/inter-protocol/src/clientSupport.js @@ -9,29 +9,31 @@ import { parseRatio } from '@agoric/zoe/src/contractSupport/ratio.js'; const COSMOS_UNIT = 1_000_000n; const scaleDecimals = num => BigInt(num * Number(COSMOS_UNIT)); +// TODO use '@satisfies" in TS 5.1 to make sure these each conform to OfferMaker interface + // NB: not really a Proposal because the brands are not remotes // Instead they're copyRecord like "{"boardId":"board0257","iface":"Alleged: IST brand"}" to pass through the boardId // mustMatch(harden(proposal), ProposalShape); /** * Give/want * - * @param {Record} brands + * @param {Pick} agoricNames * @param {{ giveMinted?: number, wantMinted?: number } | { collateralBrandKey: string, giveCollateral?: number, wantCollateral?: number }} opts * @returns {Proposal} */ -const makeVaultProposal = (brands, opts) => { +const makeVaultProposal = ({ brand }, opts) => { const proposal = { give: {}, want: {} }; if ('giveCollateral' in opts && opts.giveCollateral) { const { collateralBrandKey } = opts; proposal.give.Collateral = { - brand: brands[collateralBrandKey], + brand: brand[collateralBrandKey], value: scaleDecimals(opts.giveCollateral), }; } if ('giveMinted' in opts && opts.giveMinted) { proposal.give.Minted = { - brand: brands.IST, + brand: brand.IST, value: scaleDecimals(opts.giveMinted), }; } @@ -39,13 +41,13 @@ const makeVaultProposal = (brands, opts) => { if ('wantCollateral' in opts && opts.wantCollateral) { const { collateralBrandKey } = opts; proposal.want.Collateral = { - brand: brands[collateralBrandKey], + brand: brand[collateralBrandKey], value: scaleDecimals(opts.wantCollateral), }; } if ('wantMinted' in opts && opts.wantMinted) { proposal.want.Minted = { - brand: brands.IST, + brand: brand.IST, value: scaleDecimals(opts.wantMinted), }; } @@ -54,18 +56,18 @@ const makeVaultProposal = (brands, opts) => { }; /** - * @param {Record} brands + * @param {Pick} agoricNames * @param {{ offerId: string, wantMinted: number, giveCollateral: number, collateralBrandKey: string }} opts * @returns {import('@agoric/smart-wallet/src/offers.js').OfferSpec} */ -const makeOpenOffer = (brands, opts) => { - const proposal = makeVaultProposal(brands, opts); +const makeOpenOffer = ({ brand }, opts) => { + const proposal = makeVaultProposal({ brand }, opts); // NB: not really a Proposal because the brands are not remotes // Instead they're copyRecord like "{"boardId":"board0257","iface":"Alleged: IST brand"}" to pass through the boardId // mustMatch(harden(proposal), ProposalShape); - const collateralBrand = brands[opts.collateralBrandKey]; + const collateralBrand = brand[opts.collateralBrandKey]; return { id: opts.offerId, @@ -82,16 +84,16 @@ const makeOpenOffer = (brands, opts) => { }; /** - * @param {Record} brands + * @param {Pick} agoricNames * @param {{ offerId: string, collateralBrandKey?: string, giveCollateral?: number, wantCollateral?: number, giveMinted?: number, wantMinted?: number }} opts * @param {string} previousOffer * @returns {import('@agoric/smart-wallet/src/offers.js').OfferSpec} */ -const makeAdjustOffer = (brands, opts, previousOffer) => { +const makeAdjustOffer = ({ brand }, opts, previousOffer) => { // NB: not really a Proposal because the brands are not remotes // Instead they're copyRecord like "{"boardId":"board0257","iface":"Alleged: IST brand"}" to pass through the boardId // mustMatch(harden(proposal), ProposalShape); - const proposal = makeVaultProposal(brands, opts); + const proposal = makeVaultProposal({ brand }, opts); return { id: opts.offerId, @@ -105,13 +107,13 @@ const makeAdjustOffer = (brands, opts, previousOffer) => { }; /** - * @param {Record} brands + * @param {Pick} agoricNames * @param {{ offerId: string, collateralBrandKey?: string, giveMinted: number }} opts * @param {string} previousOffer * @returns {import('@agoric/smart-wallet/src/offers.js').OfferSpec} */ -const makeCloseOffer = (brands, opts, previousOffer) => { - const proposal = makeVaultProposal(brands, opts); +const makeCloseOffer = ({ brand }, opts, previousOffer) => { + const proposal = makeVaultProposal({ brand }, opts); return { id: opts.offerId, @@ -171,19 +173,19 @@ const makePsmProposal = (brands, opts, fee = 0, anchor = 'AUSD') => { }; /** + * @param {Pick} agoricNames * @param {Instance} instance - * @param {Record} brands * @param {{ offerId: string, feePct?: number, pair: [string, string] } & * ({ wantMinted: number } | { giveMinted: number })} opts * @returns {import('@agoric/smart-wallet/src/offers.js').OfferSpec} */ -const makePsmSwapOffer = (instance, brands, opts) => { +const makePsmSwapOffer = ({ brand }, instance, opts) => { const method = 'wantMinted' in opts ? 'makeWantMintedInvitation' : 'makeGiveMintedInvitation'; // ref psm.js const proposal = makePsmProposal( - brands, + brand, opts, opts.feePct ? opts.feePct / 100 : undefined, opts.pair[1], @@ -276,7 +278,7 @@ const makeBidOffer = (_brands, opts) => { }; /** - * @param {Record} brands + * @param {Pick} agoricNames * @param {{ * offerId: string, * give: number, @@ -284,11 +286,11 @@ const makeBidOffer = (_brands, opts) => { * }} opts * @returns {import('@agoric/smart-wallet/src/offers.js').OfferSpec} */ -const makeAddCollateralOffer = (brands, opts) => { +const makeAddCollateralOffer = ({ brand }, opts) => { /** @type {AmountKeywordRecord} */ const give = { Collateral: AmountMath.make( - brands[opts.collateralBrandKey], + brand[opts.collateralBrandKey], scaleDecimals(opts.give), ), }; @@ -308,7 +310,7 @@ const makeAddCollateralOffer = (brands, opts) => { /** * - * @param {Record} _brands + * @param {unknown} _agoricNames * @param {{ * offerId: string, * roundId?: bigint, @@ -317,7 +319,7 @@ const makeAddCollateralOffer = (brands, opts) => { * @param {string} previousOffer * @returns {import('@agoric/smart-wallet/src/offers.js').OfferSpec} */ -const makePushPriceOffer = (_brands, opts, previousOffer) => { +const makePushPriceOffer = (_agoricNames, opts, previousOffer) => { return { id: opts.offerId, invitationSpec: { diff --git a/packages/smart-wallet/src/types.d.ts b/packages/smart-wallet/src/types.d.ts index 576283999d4..6985288e42b 100644 --- a/packages/smart-wallet/src/types.d.ts +++ b/packages/smart-wallet/src/types.d.ts @@ -5,9 +5,11 @@ * Downside is it can't reference any ambient types, which most of agoric-sdk type are presently. */ -import { ERef, FarRef } from '@endo/far'; +import type { ERef, FarRef } from '@endo/far'; import type { CapData } from '@endo/marshal'; import type { MsgWalletSpendAction } from '@agoric/cosmic-proto/swingset/msgs'; +import type { AgoricNamesRemotes } from '@agoric/vats/tools/board-utils.js'; +import type { OfferSpec } from './offers.js'; declare const CapDataShape: unique symbol; @@ -74,3 +76,11 @@ export type WalletSpendActionMsg = { * the sending of the message (as is the case for WALLET_SPEND_ACTION). */ export type WalletBridgeMsg = WalletActionMsg | WalletSpendActionMsg; + +/** + * Used for clientSupport helpers + */ +export type OfferMaker = ( + agoricNames: AgoricNamesRemotes, + ...rest: any[] +) => OfferSpec; diff --git a/packages/vats/test/bootstrapTests/drivers.js b/packages/vats/test/bootstrapTests/drivers.js index 4bfa1dbb684..1046ec03dbd 100644 --- a/packages/vats/test/bootstrapTests/drivers.js +++ b/packages/vats/test/bootstrapTests/drivers.js @@ -77,25 +77,25 @@ export const makeWalletFactoryDriver = async ( return EV(walletPresence).handleBridgeAction(capData, true); }, /** - * @template {(brands: Record, ...rest: any) => import('@agoric/smart-wallet/src/offers.js').OfferSpec} M offer maker function + * @template {import('@agoric/smart-wallet/src/types.js').OfferMaker} M offer maker function * @param {M} makeOffer * @param {Parameters[1]} firstArg * @param {Parameters[2]} [secondArg] * @returns {Promise} */ executeOfferMaker(makeOffer, firstArg, secondArg) { - const offer = makeOffer(agoricNamesRemotes.brand, firstArg, secondArg); + const offer = makeOffer(agoricNamesRemotes, firstArg, secondArg); return this.executeOffer(offer); }, /** - * @template {(brands: Record, ...rest: any) => import('@agoric/smart-wallet/src/offers.js').OfferSpec} M offer maker function + * @template {import('@agoric/smart-wallet/src/types.js').OfferMaker} M offer maker function * @param {M} makeOffer * @param {Parameters[1]} firstArg * @param {Parameters[2]} [secondArg] * @returns {Promise} */ sendOfferMaker(makeOffer, firstArg, secondArg) { - const offer = makeOffer(agoricNamesRemotes.brand, firstArg, secondArg); + const offer = makeOffer(agoricNamesRemotes, firstArg, secondArg); return this.sendOffer(offer); }, diff --git a/packages/vats/test/bootstrapTests/test-liquidation-1.js b/packages/vats/test/bootstrapTests/test-liquidation-1.js index 906e69cef63..8ad077171ab 100644 --- a/packages/vats/test/bootstrapTests/test-liquidation-1.js +++ b/packages/vats/test/bootstrapTests/test-liquidation-1.js @@ -190,8 +190,8 @@ const checkFlow1 = async ( const parseAmount = makeParseAmount(agoricNamesRemotes, Error); await buyer.sendOffer( Offers.psm.swap( + agoricNamesRemotes, agoricNamesRemotes.instance['psm-IST-USDC_axl'], - agoricNamesRemotes.brand, { offerId: `print-${collateralBrandKey}-ist`, wantMinted: 1_000, diff --git a/packages/vats/test/bootstrapTests/test-liquidation-2b.js b/packages/vats/test/bootstrapTests/test-liquidation-2b.js index c958c5e3076..08ff47d87e7 100644 --- a/packages/vats/test/bootstrapTests/test-liquidation-2b.js +++ b/packages/vats/test/bootstrapTests/test-liquidation-2b.js @@ -168,8 +168,8 @@ test.serial('scenario: Flow 2b', async t => { const parseAmount = makeParseAmount(agoricNamesRemotes, Error); await buyer.sendOffer( Offers.psm.swap( + agoricNamesRemotes, agoricNamesRemotes.instance['psm-IST-USDC_axl'], - agoricNamesRemotes.brand, { offerId: 'print-ist', wantMinted: 1_000, From a48d87e6b8b90e251ca7702be96faf1491d72e7e Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Mon, 22 May 2023 13:36:46 -0700 Subject: [PATCH 2/8] refactor(clientSupport): move makeParseAmount --- packages/agoric-cli/src/commands/inter.js | 6 +- packages/agoric-cli/src/lib/wallet.js | 42 ---------- packages/inter-protocol/src/clientSupport.js | 83 +++++++++---------- .../inter-protocol/test/test-clientSupport.js | 2 +- 4 files changed, 46 insertions(+), 87 deletions(-) diff --git a/packages/agoric-cli/src/commands/inter.js b/packages/agoric-cli/src/commands/inter.js index ee7cb5abe55..9850cdc10b2 100644 --- a/packages/agoric-cli/src/commands/inter.js +++ b/packages/agoric-cli/src/commands/inter.js @@ -7,7 +7,10 @@ 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 { + Offers, + makeParseAmount, +} from '@agoric/inter-protocol/src/clientSupport.js'; import { objectMap } from '@agoric/internal'; import { M, matches } from '@agoric/store'; @@ -25,7 +28,6 @@ import { import { getNetworkConfig } from '../lib/rpc.js'; import { getCurrent, - makeParseAmount, makeWalletUtils, outputActionAndHint, sendAction, diff --git a/packages/agoric-cli/src/lib/wallet.js b/packages/agoric-cli/src/lib/wallet.js index a2da7615335..1127f63ce9e 100644 --- a/packages/agoric-cli/src/lib/wallet.js +++ b/packages/agoric-cli/src/lib/wallet.js @@ -9,7 +9,6 @@ import { boardSlottingMarshaller, makeRpcUtils } from './rpc.js'; /** @typedef {import('@agoric/smart-wallet/src/smartWallet.js').CurrentWalletRecord} CurrentWalletRecord */ /** @typedef {import('@agoric/vats/tools/board-utils.js').AgoricNamesRemotes} AgoricNamesRemotes */ -const { values } = Object; const { Fail } = assert; const marshaller = boardSlottingMarshaller(); @@ -271,44 +270,3 @@ export const makeWalletUtils = async ( pollOffer, }; }; - -/** - * @param {{ - * brand: Record, - * vbankAsset: Record, - * }} agoricNames - * @param {(msg: string) => Error} makeError error constructor - * @returns {(a: string) => Amount<'nat'>} - */ -export const makeParseAmount = - (agoricNames, makeError = msg => RangeError(msg)) => - opt => { - assert.typeof(opt, 'string', 'parseAmount expected string'); - const m = opt.match(/^(?[\d_]+(\.[\d_]+)?)(?[A-Z]\w*?)$/); - if (!m || !m.groups) { - throw makeError(`invalid amount: ${opt}`); - } - const anyBrand = agoricNames.brand[m.groups.brand]; - if (!anyBrand) { - throw makeError(`unknown brand: ${m.groups.brand}`); - } - const assetDesc = values(agoricNames.vbankAsset).find( - d => d.brand === anyBrand, - ); - if (!assetDesc) { - throw makeError(`unknown brand: ${m.groups.brand}`); - } - const { displayInfo } = assetDesc; - if (!displayInfo.decimalPlaces || displayInfo.assetKind !== 'nat') { - throw makeError(`bad brand: ${displayInfo}`); - } - const value = BigInt( - Number(m.groups.value.replace(/_/g, '')) * - 10 ** displayInfo.decimalPlaces, - ); - /** @type {Brand<'nat'>} */ - // @ts-expect-error dynamic cast - const natBrand = anyBrand; - const amt = { value, brand: natBrand }; - return amt; - }; diff --git a/packages/inter-protocol/src/clientSupport.js b/packages/inter-protocol/src/clientSupport.js index 204c5aee785..d618cb3355e 100644 --- a/packages/inter-protocol/src/clientSupport.js +++ b/packages/inter-protocol/src/clientSupport.js @@ -206,6 +206,47 @@ const makePsmSwapOffer = ({ brand }, instance, opts) => { }; }; +/** + * @param {{ + * brand: Record, + * vbankAsset: Record, + * }} agoricNames + * @param {(msg: string) => Error} makeError error constructor + * @returns {(a: string) => Amount<'nat'>} + */ +export const makeParseAmount = + (agoricNames, makeError = msg => RangeError(msg)) => + opt => { + assert.typeof(opt, 'string', 'parseAmount expected string'); + const m = opt.match(/^(?[\d_]+(\.[\d_]+)?)(?[A-Z]\w*?)$/); + if (!m || !m.groups) { + throw makeError(`invalid amount: ${opt}`); + } + const anyBrand = agoricNames.brand[m.groups.brand]; + if (!anyBrand) { + throw makeError(`unknown brand: ${m.groups.brand}`); + } + const assetDesc = Object.values(agoricNames.vbankAsset).find( + d => d.brand === anyBrand, + ); + if (!assetDesc) { + throw makeError(`unknown brand: ${m.groups.brand}`); + } + const { displayInfo } = assetDesc; + if (!displayInfo.decimalPlaces || displayInfo.assetKind !== 'nat') { + throw makeError(`bad brand: ${displayInfo}`); + } + const value = BigInt( + Number(m.groups.value.replace(/_/g, '')) * + 10 ** displayInfo.decimalPlaces, + ); + /** @type {Brand<'nat'>} */ + // @ts-expect-error dynamic cast + const natBrand = anyBrand; + const amt = { value, brand: natBrand }; + return amt; + }; + /** * @param {Record} _brands * @param {{ @@ -334,48 +375,6 @@ const makePushPriceOffer = (_agoricNames, opts, previousOffer) => { }; }; -// TODO DRY with CLI wallet.js -/** - * @param {{ - * brand: Record, - * vbankAsset: Record, - * }} agoricNames - * @param {(msg: string) => Error} makeError error constructor - * @returns {(a: string) => Amount<'nat'>} - */ -export const makeParseAmount = - (agoricNames, makeError = msg => RangeError(msg)) => - opt => { - assert.typeof(opt, 'string', 'parseAmount expected string'); - const m = opt.match(/^(?[\d_]+(\.[\d_]+)?)(?[A-Z]\w*?)$/); - if (!m || !m.groups) { - throw makeError(`invalid amount: ${opt}`); - } - const anyBrand = agoricNames.brand[m.groups.brand]; - if (!anyBrand) { - throw makeError(`unknown brand: ${m.groups.brand}`); - } - const assetDesc = Object.values(agoricNames.vbankAsset).find( - d => d.brand === anyBrand, - ); - if (!assetDesc) { - throw makeError(`unknown brand: ${m.groups.brand}`); - } - const { displayInfo } = assetDesc; - if (!displayInfo.decimalPlaces || displayInfo.assetKind !== 'nat') { - throw makeError(`bad brand: ${displayInfo}`); - } - const value = BigInt( - Number(m.groups.value.replace(/_/g, '')) * - 10 ** displayInfo.decimalPlaces, - ); - /** @type {Brand<'nat'>} */ - // @ts-expect-error dynamic cast - const natBrand = anyBrand; - const amt = { value, brand: natBrand }; - return amt; - }; - export const Offers = { auction: { Bid: makeBidOffer, diff --git a/packages/inter-protocol/test/test-clientSupport.js b/packages/inter-protocol/test/test-clientSupport.js index c8586afb481..34432f17ece 100644 --- a/packages/inter-protocol/test/test-clientSupport.js +++ b/packages/inter-protocol/test/test-clientSupport.js @@ -2,8 +2,8 @@ import { test } from '@agoric/zoe/tools/prepare-test-env-ava.js'; import { makeIssuerKit } from '@agoric/ertp'; import { makeRatio } from '@agoric/zoe/src/contractSupport/ratio.js'; -import { withAmountUtils } from './supports.js'; import { makeParseAmount, Offers } from '../src/clientSupport.js'; +import { withAmountUtils } from './supports.js'; const ist = withAmountUtils(makeIssuerKit('IST')); const atom = withAmountUtils(makeIssuerKit('ATOM')); From 1ba69dcbffa48fc60d15cf4e188cc10adb27f51d Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Mon, 22 May 2023 13:49:15 -0700 Subject: [PATCH 3/8] refactor(clientSupport): inline parseAmount --- packages/agoric-cli/src/commands/inter.js | 23 +++---------------- packages/inter-protocol/src/clientSupport.js | 8 +++---- .../inter-protocol/test/test-clientSupport.js | 19 +++++++-------- .../test/bootstrapTests/test-liquidation-1.js | 15 ++++++------ .../bootstrapTests/test-liquidation-2b.js | 7 +----- .../bootstrapTests/test-vaults-integration.js | 14 +---------- 6 files changed, 23 insertions(+), 63 deletions(-) diff --git a/packages/agoric-cli/src/commands/inter.js b/packages/agoric-cli/src/commands/inter.js index 9850cdc10b2..1b691d08fef 100644 --- a/packages/agoric-cli/src/commands/inter.js +++ b/packages/agoric-cli/src/commands/inter.js @@ -7,10 +7,7 @@ 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, - makeParseAmount, -} from '@agoric/inter-protocol/src/clientSupport.js'; +import { Offers } from '@agoric/inter-protocol/src/clientSupport.js'; import { objectMap } from '@agoric/internal'; import { M, matches } from '@agoric/store'; @@ -417,14 +414,7 @@ inter auction status async ({ generateOnly, dryRun, ...opts }) => { const tools = await tryMakeUtils(); - const parseAmount = makeParseAmount( - tools.agoricNames, - msg => new InvalidArgumentError(msg), - ); - const offer = Offers.auction.Bid(tools.agoricNames.brand, { - ...opts, - parseAmount, - }); + const offer = Offers.auction.Bid(tools.agoricNames, opts); if (generateOnly) { outputActionAndHint( @@ -465,14 +455,7 @@ inter auction status async ({ generateOnly, ...opts }) => { const tools = await tryMakeUtils(); - const parseAmount = makeParseAmount( - tools.agoricNames, - msg => new InvalidArgumentError(msg), - ); - const offer = Offers.auction.Bid(tools.agoricNames.brand, { - ...opts, - parseAmount, - }); + const offer = Offers.auction.Bid(tools.agoricNames, opts); if (generateOnly) { outputActionAndHint( { method: 'executeOffer', offer }, diff --git a/packages/inter-protocol/src/clientSupport.js b/packages/inter-protocol/src/clientSupport.js index d618cb3355e..26cf145f149 100644 --- a/packages/inter-protocol/src/clientSupport.js +++ b/packages/inter-protocol/src/clientSupport.js @@ -248,13 +248,12 @@ export const makeParseAmount = }; /** - * @param {Record} _brands + * @param {Pick} agoricNames * @param {{ * offerId: string, * give: string, * maxBuy: string, * wantMinimum?: string, - * parseAmount: (x: string) => Amount<'nat'>, * } & ({ * price: number, * } | { @@ -262,14 +261,13 @@ export const makeParseAmount = * })} opts * @returns {import('@agoric/smart-wallet/src/offers.js').OfferSpec} */ -const makeBidOffer = (_brands, opts) => { - assert.typeof(opts.parseAmount, 'function'); +const makeBidOffer = (agoricNames, opts) => { assertAllDefined({ offerId: opts.offerId, give: opts.give, maxBuy: opts.maxBuy, }); - const { parseAmount } = opts; + const parseAmount = makeParseAmount(agoricNames); const proposal = { give: { Bid: parseAmount(opts.give) }, ...(opts.wantMinimum diff --git a/packages/inter-protocol/test/test-clientSupport.js b/packages/inter-protocol/test/test-clientSupport.js index 34432f17ece..fce5d2476aa 100644 --- a/packages/inter-protocol/test/test-clientSupport.js +++ b/packages/inter-protocol/test/test-clientSupport.js @@ -2,7 +2,7 @@ import { test } from '@agoric/zoe/tools/prepare-test-env-ava.js'; import { makeIssuerKit } from '@agoric/ertp'; import { makeRatio } from '@agoric/zoe/src/contractSupport/ratio.js'; -import { makeParseAmount, Offers } from '../src/clientSupport.js'; +import { Offers } from '../src/clientSupport.js'; import { withAmountUtils } from './supports.js'; const ist = withAmountUtils(makeIssuerKit('IST')); @@ -13,7 +13,9 @@ const brands = { ATOM: atom.brand, }; -const agoricNames = /** @type {const} */ ({ +// XXX use @satisfies +/** @type {import('@agoric/vats/tools/board-utils.js').AgoricNamesRemotes} */ +const agoricNames = /** @type {any} */ ({ brand: brands, vbankAsset: { uist: { @@ -43,16 +45,14 @@ test('Offers.auction.Bid', async t => { { cliArg: -0.1, offerBidScaling: makeRatio(110n, ist.brand, 100n) }, ]; - const parseAmount = makeParseAmount(agoricNames); discounts.forEach(({ cliArg, offerBidScaling }) => { t.log('discount', cliArg * 100, '%'); t.deepEqual( - Offers.auction.Bid(brands, { + Offers.auction.Bid(agoricNames, { offerId: 'foo1', give: '4.56IST', discount: cliArg, maxBuy: '10_000ATOM', - parseAmount, }), { id: 'foo1', @@ -75,12 +75,11 @@ test('Offers.auction.Bid', async t => { const price = 7; const offerPrice = makeRatio(7n, ist.brand, 1n, atom.brand); t.deepEqual( - Offers.auction.Bid(brands, { + Offers.auction.Bid(agoricNames, { offerId: 'by-price2', give: '4.56IST', price, maxBuy: '10_000ATOM', - parseAmount, }), { id: 'by-price2', @@ -98,13 +97,12 @@ test('Offers.auction.Bid', async t => { ); t.deepEqual( - Offers.auction.Bid(brands, { + Offers.auction.Bid(agoricNames, { offerId: 'by-price2', maxBuy: '10_000ATOM', wantMinimum: '1.23ATOM', give: '4.56IST', price, - parseAmount, }), { id: 'by-price2', @@ -128,12 +126,11 @@ test('Offers.auction.Bid', async t => { t.throws( () => // @ts-expect-error error checking test - Offers.auction.Bid(brands, { + Offers.auction.Bid(agoricNames, { offerId: 'by-price2', wantMinimum: '1.23ATOM', give: '4.56IST', price, - parseAmount, }), { message: 'missing ["maxBuy"]' }, ); diff --git a/packages/vats/test/bootstrapTests/test-liquidation-1.js b/packages/vats/test/bootstrapTests/test-liquidation-1.js index 8ad077171ab..1af0ee503d8 100644 --- a/packages/vats/test/bootstrapTests/test-liquidation-1.js +++ b/packages/vats/test/bootstrapTests/test-liquidation-1.js @@ -5,10 +5,7 @@ import { test as anyTest } from '@agoric/zoe/tools/prepare-test-env-ava.js'; import { NonNullish } from '@agoric/assert'; -import { - makeParseAmount, - Offers, -} from '@agoric/inter-protocol/src/clientSupport.js'; +import { Offers } from '@agoric/inter-protocol/src/clientSupport.js'; import process from 'process'; import { likePayouts, @@ -128,6 +125,12 @@ test.after.always(t => { }); // Reference: Flow 1 from https://github.com/Agoric/agoric-sdk/issues/7123 +/** + * + * @param {import('ava').ExecutionContext>>} t + * @param {{collateralBrandKey: string, managerIndex: number}} case + * @param {*} _expected + */ const checkFlow1 = async ( t, { collateralBrandKey, managerIndex }, @@ -187,7 +190,6 @@ const checkFlow1 = async ( // Place bids // --------------- - const parseAmount = makeParseAmount(agoricNamesRemotes, Error); await buyer.sendOffer( Offers.psm.swap( agoricNamesRemotes, @@ -207,7 +209,6 @@ const checkFlow1 = async ( offerId: `${collateralBrandKey}-bid1`, ...setup.bids[0], maxBuy, - parseAmount, }); t.like(readLatest('published.wallet.agoric1buyer'), { @@ -221,7 +222,6 @@ const checkFlow1 = async ( offerId: `${collateralBrandKey}-bid2`, ...setup.bids[1], maxBuy, - parseAmount, }); t.like(readLatest('published.wallet.agoric1buyer'), { status: { @@ -234,7 +234,6 @@ const checkFlow1 = async ( offerId: `${collateralBrandKey}-bid3`, ...setup.bids[2], maxBuy, - parseAmount, }); t.like(readLatest('published.wallet.agoric1buyer'), { status: { diff --git a/packages/vats/test/bootstrapTests/test-liquidation-2b.js b/packages/vats/test/bootstrapTests/test-liquidation-2b.js index 08ff47d87e7..4d8294c4ff4 100644 --- a/packages/vats/test/bootstrapTests/test-liquidation-2b.js +++ b/packages/vats/test/bootstrapTests/test-liquidation-2b.js @@ -8,10 +8,7 @@ import { test as anyTest } from '@agoric/zoe/tools/prepare-test-env-ava.js'; import { NonNullish } from '@agoric/assert'; -import { - makeParseAmount, - Offers, -} from '@agoric/inter-protocol/src/clientSupport.js'; +import { Offers } from '@agoric/inter-protocol/src/clientSupport.js'; import { makeLiquidationTestContext, scale6 } from './liquidation.js'; /** @@ -165,7 +162,6 @@ test.serial('scenario: Flow 2b', async t => { // Place bids // --------------- - const parseAmount = makeParseAmount(agoricNamesRemotes, Error); await buyer.sendOffer( Offers.psm.swap( agoricNamesRemotes, @@ -187,7 +183,6 @@ test.serial('scenario: Flow 2b', async t => { offerId, ...setup.bids[i], maxBuy, - parseAmount, }); t.like(readLatest('published.wallet.agoric1buyer'), { status: { diff --git a/packages/vats/test/bootstrapTests/test-vaults-integration.js b/packages/vats/test/bootstrapTests/test-vaults-integration.js index 2958dd622a2..084ba75e8c8 100644 --- a/packages/vats/test/bootstrapTests/test-vaults-integration.js +++ b/packages/vats/test/bootstrapTests/test-vaults-integration.js @@ -253,7 +253,7 @@ test('open vault with insufficient funds gives helpful error', async t => { }); test('exit bid', async t => { - const { walletFactoryDriver, agoricNamesRemotes } = t.context; + const { walletFactoryDriver } = t.context; const wd = await walletFactoryDriver.provideSmartWallet('agoric1bid'); @@ -265,23 +265,11 @@ test('exit bid', async t => { giveCollateral: 9.0, }); - const parseAmount = opt => { - const m = opt.match(/^(?[\d_.]+)(?\w+?)$/); - assert(m); - return { - value: BigInt(Number(m.groups.value.replace(/_/g, '')) * 1_000_000), - /** @type {Brand<'nat'>} */ - // @ts-expect-error mock - brand: agoricNamesRemotes.brand[m.groups.brand], - }; - }; - wd.sendOfferMaker(Offers.auction.Bid, { offerId: 'bid', maxBuy: '1.23ATOM', give: '0.1IST', price: 5, - parseAmount, }); await wd.tryExitOffer('bid'); From e77b01d6ab90ade5c499324b0d821ccac705a91f Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Thu, 15 Jun 2023 13:50:38 -0700 Subject: [PATCH 4/8] chore!: restrict exports from 'agoric' package it's only for installing the bin and importing that bin module --- packages/agoric-cli/package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/agoric-cli/package.json b/packages/agoric-cli/package.json index 7ea606ab242..079702a42c4 100644 --- a/packages/agoric-cli/package.json +++ b/packages/agoric-cli/package.json @@ -8,6 +8,9 @@ "agoric": "src/entrypoint.js", "agops": "src/bin-agops.js" }, + "exports": { + "./src/entrypoint.js": "./src/entrypoint.js" + }, "files": [ "src", "exported.js" From 175eb888aefae8bda807172a0cfe79017cc49b26 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Thu, 15 Jun 2023 13:50:57 -0700 Subject: [PATCH 5/8] chore(deps): remove dep on 'agoric' --- packages/inter-protocol/package.json | 1 - packages/solo/package.json | 1 - packages/wallet/package.json | 1 - 3 files changed, 3 deletions(-) diff --git a/packages/inter-protocol/package.json b/packages/inter-protocol/package.json index dbd77389b87..d8242b1ee2f 100644 --- a/packages/inter-protocol/package.json +++ b/packages/inter-protocol/package.json @@ -45,7 +45,6 @@ "@endo/far": "^0.2.18", "@endo/marshal": "^0.8.5", "@endo/nat": "^4.1.27", - "agoric": "^0.21.1", "jessie.js": "^0.3.2" }, "devDependencies": { diff --git a/packages/solo/package.json b/packages/solo/package.json index 0ffff51c1a2..cdc4119f218 100644 --- a/packages/solo/package.json +++ b/packages/solo/package.json @@ -42,7 +42,6 @@ "@endo/init": "^0.5.56", "@endo/marshal": "^0.8.5", "@endo/promise-kit": "^0.2.56", - "agoric": "^0.21.1", "anylogger": "^0.21.0", "deterministic-json": "^1.0.5", "esm": "agoric-labs/esm#Agoric-built", diff --git a/packages/wallet/package.json b/packages/wallet/package.json index 82702d15d82..21c17502771 100644 --- a/packages/wallet/package.json +++ b/packages/wallet/package.json @@ -20,7 +20,6 @@ }, "dependencies": { "@agoric/wallet-ui": "0.1.3-solo.0", - "agoric": "^0.21.1", "babel-eslint": "^10.0.3", "eslint-plugin-eslint-comments": "^3.1.2", "import-meta-resolve": "^2.2.1" From 6fa09da79468a180ce97cd974a7741d052fa024e Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Tue, 13 Jun 2023 13:33:42 -0700 Subject: [PATCH 6/8] ci: tighten cycles limit --- .github/workflows/test-all-packages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-all-packages.yml b/.github/workflows/test-all-packages.yml index 26a9d5c4cc1..3c26542a2c3 100644 --- a/.github/workflows/test-all-packages.yml +++ b/.github/workflows/test-all-packages.yml @@ -49,7 +49,7 @@ jobs: run: sudo apt install -y graphviz - name: Check for cycles - run: scripts/check-dependency-cycles.sh 4 + run: scripts/check-dependency-cycles.sh 3 ################## # Lint tests From 2aa9173bbbdff51c7a3a9197ce772f44d09438a9 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Thu, 15 Jun 2023 13:53:40 -0700 Subject: [PATCH 7/8] build: gitignore graph script output --- .gitignore | 2 +- scripts/graph.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 46114b99308..6b27e826198 100644 --- a/.gitignore +++ b/.gitignore @@ -63,7 +63,7 @@ dist .vscode/ .idea/ -/packages.png +/packages-graph* chaintest _testoutput.txt diff --git a/scripts/graph.sh b/scripts/graph.sh index 3e7af7ef485..ae82ab06b34 100755 --- a/scripts/graph.sh +++ b/scripts/graph.sh @@ -25,9 +25,9 @@ dot -Tpng "$DIR"/../packages-graph.png dot -Tsvg "$DIR"/../packages-graph.svg -if acyclic packages-graph.dot | dot -Tcanon >packages-sans-cycles.dot; then +if acyclic packages-graph.dot | dot -Tcanon >packages-graph-sans-cycles.dot; then echo "No cycles in 'dependencies' of packages." else echo "Cycles detected. These lines appear only in the original graph and not the acyclic variant:" - comm -23 <(sort packages-graph.dot) <(sort packages-sans-cycles.dot) + comm -23 <(sort packages-graph.dot) <(sort packages-graph-sans-cycles.dot) fi From b262241b5de98af9784db940b6b556eb79d6d014 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Thu, 22 Jun 2023 12:18:10 -0700 Subject: [PATCH 8/8] build: export for loadgen until https://github.com/Agoric/testnet-load-generator/issues/112 --- packages/agoric-cli/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/agoric-cli/package.json b/packages/agoric-cli/package.json index 079702a42c4..96f0ed4b37a 100644 --- a/packages/agoric-cli/package.json +++ b/packages/agoric-cli/package.json @@ -9,7 +9,8 @@ "agops": "src/bin-agops.js" }, "exports": { - "./src/entrypoint.js": "./src/entrypoint.js" + "./src/entrypoint.js": "./src/entrypoint.js", + "./src/helpers.js": "./src/helpers.js" }, "files": [ "src",