diff --git a/packages/ERTP/src/typeGuards.js b/packages/ERTP/src/typeGuards.js index c503f27bb50..2d26319aed3 100644 --- a/packages/ERTP/src/typeGuards.js +++ b/packages/ERTP/src/typeGuards.js @@ -124,18 +124,19 @@ export const MAX_ABSOLUTE_DECIMAL_PLACES = 100; export const AssetKindShape = M.or('nat', 'set', 'copySet', 'copyBag'); -export const DisplayInfoShape = M.partial( - harden({ +export const DisplayInfoShape = M.splitRecord( + {}, + { decimalPlaces: M.and( M.gte(-MAX_ABSOLUTE_DECIMAL_PLACES), M.lte(MAX_ABSOLUTE_DECIMAL_PLACES), ), assetKind: AssetKindShape, - }), - harden({ + }, + { // Including this empty `rest` ensures that there are no other // properties beyond those in the `base` record. - }), + }, ); // //////////////////////// Interfaces ///////////////////////////////////////// diff --git a/packages/SwingSet/src/typeGuards.js b/packages/SwingSet/src/typeGuards.js index 3ffe089b7d8..4a8ccc5bf12 100644 --- a/packages/SwingSet/src/typeGuards.js +++ b/packages/SwingSet/src/typeGuards.js @@ -3,16 +3,17 @@ import { M } from '@agoric/store'; export const ManagerType = M.or('xs-worker', 'local'); // TODO: others -const Bundle = M.split({ moduleType: M.string() }, M.partial({})); +const Bundle = M.splitRecord({ moduleType: M.string() }); + +const SwingsetConfigOptions = harden({ + creationOptions: M.splitRecord({}, { critial: M.boolean() }), + parameters: M.recordOf(M.string(), M.any()), +}); -const p1 = M.and( - M.partial({ creationOptions: M.partial({ critial: M.boolean() }) }), - M.partial({ parameters: M.recordOf(M.string(), M.any()) }), -); const SwingSetConfigProperties = M.or( - M.split({ sourceSpec: M.string() }, p1), - M.split({ bundleSpec: M.string() }, p1), - M.split({ bundle: Bundle }, p1), + M.splitRecord({ sourceSpec: M.string() }, SwingsetConfigOptions), + M.splitRecord({ bundleSpec: M.string() }, SwingsetConfigOptions), + M.splitRecord({ bundle: Bundle }, SwingsetConfigOptions), ); const SwingSetConfigDescriptor = M.recordOf( M.string(), @@ -30,11 +31,11 @@ const SwingSetConfigDescriptor = M.recordOf( * in ./types-external.js */ export const SwingSetConfig = M.and( - M.partial({ defaultManagerType: ManagerType }), - M.partial({ includeDevDependencies: M.boolean() }), - M.partial({ defaultReapInterval: M.number() }), // not in type decl - M.partial({ snapshotInterval: M.number() }), - M.partial({ vats: SwingSetConfigDescriptor }), - M.partial({ bootstrap: M.string() }), - M.partial({ bundles: SwingSetConfigDescriptor }), + M.splitRecord({}, { defaultManagerType: ManagerType }), + M.splitRecord({}, { includeDevDependencies: M.boolean() }), + M.splitRecord({}, { defaultReapInterval: M.number() }), // not in type decl + M.splitRecord({}, { snapshotInterval: M.number() }), + M.splitRecord({}, { vats: SwingSetConfigDescriptor }), + M.splitRecord({}, { bootstrap: M.string() }), + M.splitRecord({}, { bundles: SwingSetConfigDescriptor }), ); diff --git a/packages/casting/src/netconfig.js b/packages/casting/src/netconfig.js index 6cb4d04cea1..dd27d92aae8 100644 --- a/packages/casting/src/netconfig.js +++ b/packages/casting/src/netconfig.js @@ -14,12 +14,12 @@ import { fit, M } from '@agoric/store'; * @property {string[]} [peers] - a list of nodes used to start the p2p gossip (stored in a per-node “address book”, which is a file stored in that node’s data directory) * @property {string[]} [seeds] - nodes which tell you about other peers but don't gossip actual data */ -export const NetworkConfigShape = M.split( - { +export const NetworkConfigShape = M.splitRecord( + harden({ chainName: M.string(), rpcAddrs: M.arrayOf(M.string()), - }, - M.partial({ + }), + harden({ apiAddrs: M.arrayOf(M.string()), gci: M.string(), peers: M.arrayOf(M.string()), diff --git a/packages/inter-protocol/src/psm/psm.js b/packages/inter-protocol/src/psm/psm.js index 35bc3e1df45..6cb55dd967a 100644 --- a/packages/inter-protocol/src/psm/psm.js +++ b/packages/inter-protocol/src/psm/psm.js @@ -276,7 +276,7 @@ export const start = async (zcf, privateArgs, baggage) => { wantmintedHook, 'wantMinted', undefined, - M.split({ + M.splitRecord({ give: { In: anchorAmountShape }, want: M.or({ Out: stableAmountShape }, {}), }), @@ -287,7 +287,7 @@ export const start = async (zcf, privateArgs, baggage) => { giveMintedHook, 'giveMinted', undefined, - M.split({ + M.splitRecord({ give: { In: stableAmountShape }, want: M.or({ Out: anchorAmountShape }, {}), }), diff --git a/packages/inter-protocol/src/psm/psmCharter.js b/packages/inter-protocol/src/psm/psmCharter.js index 926aaa15ea2..3f39ff192e3 100644 --- a/packages/inter-protocol/src/psm/psmCharter.js +++ b/packages/inter-protocol/src/psm/psmCharter.js @@ -23,17 +23,15 @@ import { E } from '@endo/far'; * @property {Record} params * @property {{paramPath: { key: string }}} [path] */ -const ParamChangesOfferArgsShape = harden( - M.split( - { - deadline: TimestampShape, - instance: InstanceHandleShape, - params: M.recordOf(M.string(), M.any()), - }, - M.partial({ - path: { paramPath: { key: M.string() } }, - }), - ), +const ParamChangesOfferArgsShape = M.splitRecord( + { + deadline: TimestampShape, + instance: InstanceHandleShape, + params: M.recordOf(M.string(), M.any()), + }, + { + path: { paramPath: { key: M.string() } }, + }, ); /** diff --git a/packages/inter-protocol/src/vaultFactory/params.js b/packages/inter-protocol/src/vaultFactory/params.js index 765b94354d0..be9d7bdfe42 100644 --- a/packages/inter-protocol/src/vaultFactory/params.js +++ b/packages/inter-protocol/src/vaultFactory/params.js @@ -78,16 +78,13 @@ const makeVaultParamManager = (publisherKit, initial) => }); /** @typedef {ReturnType} VaultParamManager */ -export const vaultParamPattern = M.split( - { - liquidationMargin: ratioPattern, - liquidationPenalty: ratioPattern, - interestRate: ratioPattern, - loanFee: ratioPattern, - debtLimit: amountPattern, - }, - M.any(), -); +export const vaultParamPattern = M.splitRecord({ + liquidationMargin: ratioPattern, + liquidationPenalty: ratioPattern, + interestRate: ratioPattern, + loanFee: ratioPattern, + debtLimit: amountPattern, +}); /** * @param {import('@agoric/notifier').StoredPublisherKit} publisherKit diff --git a/packages/smart-wallet/src/typeGuards.js b/packages/smart-wallet/src/typeGuards.js index 774ebc1ce0a..a8b1f324f5d 100644 --- a/packages/smart-wallet/src/typeGuards.js +++ b/packages/smart-wallet/src/typeGuards.js @@ -12,25 +12,25 @@ export const shape = { }, // invitations - ContractInvitationSpec: M.split( + ContractInvitationSpec: M.splitRecord( { source: 'contract', instance: InstanceHandleShape, publicInvitationMaker: M.string(), }, - M.partial({ + { invitationArgs: M.array(), - }), + }, ), - ContinuingInvitationSpec: M.split( + ContinuingInvitationSpec: M.splitRecord( { source: 'continuing', previousOffer: M.or(M.number(), M.string()), invitationMakerName: M.string(), }, - M.partial({ + { invitationArgs: M.array(), - }), + }, ), PurseInvitationSpec: { source: 'purse', @@ -39,24 +39,25 @@ export const shape = { }, // offers - OfferSpec: M.split( + OfferSpec: M.splitRecord( { id: M.or(M.number(), M.string()), // TODO M.unknown() to defer validation invitationSpec: M.any(), proposal: ProposalShape, }, - M.partial({ offerArgs: M.any() }), + { offerArgs: M.any() }, ), // walletFactory - WalletBridgeMsg: M.split( + WalletBridgeMsg: M.splitRecord( { owner: M.string(), type: M.string(), blockHeight: M.number(), blockTime: M.number(), }, + {}, M.or({ action: M.string() }, { spendAction: M.string() }), ), }; diff --git a/packages/smart-wallet/src/walletFactory.js b/packages/smart-wallet/src/walletFactory.js index 33866e85cf5..0208443cf92 100644 --- a/packages/smart-wallet/src/walletFactory.js +++ b/packages/smart-wallet/src/walletFactory.js @@ -17,9 +17,9 @@ import { shape } from './typeGuards.js'; import '@agoric/vats/exported.js'; const PrivateArgsShape = harden( - M.split( + M.splitRecord( { storageNode: M.eref(M.any()) }, - M.partial({ bridgeManager: M.eref(M.any()) }), + { bridgeManager: M.eref(M.any()) }, ), ); diff --git a/packages/vats/src/core/boot-psm.js b/packages/vats/src/core/boot-psm.js index 7449c64c1fa..5bcc06c50e3 100644 --- a/packages/vats/src/core/boot-psm.js +++ b/packages/vats/src/core/boot-psm.js @@ -92,19 +92,22 @@ export const agoricNamesReserved = harden( * decimalPlaces?: number * }} AnchorOptions */ -const AnchorOptionsShape = M.split( +const AnchorOptionsShape = M.splitRecord( { denom: M.string() }, - M.partial({ + { keyword: M.string(), proposedName: M.string(), decimalPlaces: M.number(), - }), + }, ); -export const ParametersShape = M.partial({ - anchorAssets: M.arrayOf(AnchorOptionsShape), - economicCommitteeAddresses: M.recordOf(M.string(), M.string()), -}); +export const ParametersShape = M.splitRecord( + {}, + { + anchorAssets: M.arrayOf(AnchorOptionsShape), + economicCommitteeAddresses: M.recordOf(M.string(), M.string()), + }, +); /** * Build root object of the PSM-only bootstrap vat. diff --git a/packages/zoe/src/contracts/coveredCall-durable.js b/packages/zoe/src/contracts/coveredCall-durable.js index a2bb891aae0..e1ee291afb8 100644 --- a/packages/zoe/src/contracts/coveredCall-durable.js +++ b/packages/zoe/src/contracts/coveredCall-durable.js @@ -58,7 +58,7 @@ const start = async (zcf, _privateArgs, instanceBaggage) => { const makeOption = sellSeat => { fit( sellSeat.getProposal(), - M.split({ exit: { afterDeadline: M.any() } }), + M.splitRecord({ exit: { afterDeadline: M.any() } }), 'exit afterDeadline', ); const sellSeatExitRule = sellSeat.getProposal().exit; diff --git a/packages/zoe/src/contracts/coveredCall.js b/packages/zoe/src/contracts/coveredCall.js index d3dacce540d..274af6b1419 100644 --- a/packages/zoe/src/contracts/coveredCall.js +++ b/packages/zoe/src/contracts/coveredCall.js @@ -72,7 +72,7 @@ const start = zcf => { const makeOption = sellSeat => { fit( sellSeat.getProposal(), - M.split({ exit: { afterDeadline: M.any() } }), + M.splitRecord({ exit: { afterDeadline: M.any() } }), 'exit afterDeadline', ); const sellSeatExitRule = sellSeat.getProposal().exit; diff --git a/packages/zoe/src/typeGuards.js b/packages/zoe/src/typeGuards.js index 8fa14f7a9d4..1129190897e 100644 --- a/packages/zoe/src/typeGuards.js +++ b/packages/zoe/src/typeGuards.js @@ -27,10 +27,11 @@ export const TimerShape = makeHandleShape('timer'); export const FullProposalShape = harden({ want: AmountPatternKeywordRecordShape, give: AmountKeywordRecordShape, - // To accept only one, we could use M.or rather than M.partial, + // To accept only one, we could use M.or rather than M.splitRecord, // but the error messages would have been worse. Rather, // cleanProposal's assertExit checks that there's exactly one. - exit: M.partial( + exit: M.splitRecord( + {}, { onDemand: null, waived: null, @@ -43,7 +44,7 @@ export const FullProposalShape = harden({ ), }); /** @see {Proposal} type */ -export const ProposalShape = M.partial(FullProposalShape); +export const ProposalShape = M.splitRecord({}, FullProposalShape, {}); export const isOnDemandExitRule = exit => { const [exitKey] = Object.getOwnPropertyNames(exit); @@ -68,7 +69,7 @@ export const isAfterDeadlineExitRule = exit => { return exitKey === 'afterDeadline'; }; -export const InvitationElementShape = M.split({ +export const InvitationElementShape = M.splitRecord({ description: M.string(), handle: InvitationHandleShape, instance: InstanceHandleShape,