From efdf39f9c839cb26fe6035c9ce433e2bfdb651a1 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Fri, 31 May 2024 17:29:57 -0700 Subject: [PATCH 1/2] feat(types): loadVat WellKnownVats --- .../src/proposals/orchestration-proposal.js | 6 ---- packages/smart-wallet/test/supports.js | 7 +---- packages/vats/src/core/basic-behaviors.js | 17 +++------- packages/vats/src/core/chain-behaviors.js | 17 +++------- packages/vats/src/core/demoIssuers.js | 3 +- packages/vats/src/core/types-ambient.d.ts | 31 ++++++++++++++++--- .../vats/src/proposals/localchain-proposal.js | 1 - .../vats/src/proposals/network-proposal.js | 1 - .../vats/test/vat-bank-integration.test.js | 4 +-- 9 files changed, 37 insertions(+), 50 deletions(-) diff --git a/packages/orchestration/src/proposals/orchestration-proposal.js b/packages/orchestration/src/proposals/orchestration-proposal.js index b45ff54cff1..b9b69beb96e 100644 --- a/packages/orchestration/src/proposals/orchestration-proposal.js +++ b/packages/orchestration/src/proposals/orchestration-proposal.js @@ -16,7 +16,6 @@ const trace = makeTracer('CoreEvalOrchestration', true); /** * @param {BootstrapPowers & { * consume: { - * loadCriticalVat: VatLoader; * portAllocator: PortAllocator; * }; * produce: { @@ -26,10 +25,6 @@ const trace = makeTracer('CoreEvalOrchestration', true); * }; * }} powers * @param {{ options: { orchestrationRef: VatSourceRef } }} options - * - * @typedef {{ - * orchestration: ERef; - * }} OrchestrationVats */ export const setupOrchestrationVat = async ( { @@ -43,7 +38,6 @@ export const setupOrchestrationVat = async ( options, ) => { const { orchestrationRef } = options.options; - /** @type {OrchestrationVats} */ const vats = { orchestration: E(loadCriticalVat)('orchestration', orchestrationRef), }; diff --git a/packages/smart-wallet/test/supports.js b/packages/smart-wallet/test/supports.js index 65fd4a2365e..3d22cf589db 100644 --- a/packages/smart-wallet/test/supports.js +++ b/packages/smart-wallet/test/supports.js @@ -100,12 +100,7 @@ const makeFakeBridgeManager = () => export const makeMockTestSpace = async log => { const space = /** @type {any} */ (makePromiseSpace(log)); /** - * @type {BootstrapPowers & { - * consume: { - * loadVat: (n: 'mints') => MintsVat; - * loadCriticalVat: (n: 'mints') => MintsVat; - * }; - * }} + * @type {BootstrapPowers} */ const { consume, produce } = space; const { agoricNames, agoricNamesAdmin, spaces } = diff --git a/packages/vats/src/core/basic-behaviors.js b/packages/vats/src/core/basic-behaviors.js index e1ed1a1fc0f..18434e61548 100644 --- a/packages/vats/src/core/basic-behaviors.js +++ b/packages/vats/src/core/basic-behaviors.js @@ -50,7 +50,6 @@ const bootMsgEx = { */ /** @typedef {MapStore} VatStore */ -/** @typedef {ERef>} ZoeVat */ /** * @param {BootstrapPowers & {}} powers @@ -329,9 +328,7 @@ export const produceStartGovernedUpgradable = async ({ harden(produceStartGovernedUpgradable); /** - * @param {BootstrapPowers & { - * consume: { loadCriticalVat: ERef> }; - * }} powers + * @param {BootstrapPowers} powers */ export const buildZoe = async ({ consume: { vatAdminSvc, loadCriticalVat, client }, @@ -360,9 +357,7 @@ export const buildZoe = async ({ harden(buildZoe); /** - * @param {BootstrapPowers & { - * consume: { loadCriticalVat: ERef> }; - * }} powers + * @param {BootstrapPowers} powers */ export const startPriceAuthorityRegistry = async ({ consume: { loadCriticalVat, client }, @@ -418,9 +413,7 @@ harden(produceBoard); /** * @deprecated use produceBoard - * @param {BootstrapPowers & { - * consume: { loadCriticalVat: ERef> }; - * }} powers + * @param {BootstrapPowers} powers */ export const makeBoard = async ({ consume: { loadCriticalVat, client }, @@ -607,9 +600,7 @@ harden(mintInitialSupply); /** * Add IST (with initialSupply payment), BLD (with mint) to BankManager. * - * @param {BootstrapSpace & { - * consume: { loadCriticalVat: ERef> }; - * }} powers + * @param {BootstrapSpace} powers */ export const addBankAssets = async ({ consume: { diff --git a/packages/vats/src/core/chain-behaviors.js b/packages/vats/src/core/chain-behaviors.js index 2cdaafc8489..2c1eb9ba3a9 100644 --- a/packages/vats/src/core/chain-behaviors.js +++ b/packages/vats/src/core/chain-behaviors.js @@ -109,9 +109,7 @@ export const bridgeCoreEval = async allPowers => { harden(bridgeCoreEval); /** - * @param {BootstrapPowers & { - * consume: { loadCriticalVat: ERef> }; - * }} powers + * @param {BootstrapPowers} powers */ export const makeProvisioner = async ({ consume: { clientCreator, loadCriticalVat }, @@ -303,10 +301,7 @@ export const startTimerService = async ({ harden(startTimerService); /** - * @param {BootDevices & - * BootstrapSpace & { - * consume: { loadCriticalVat: ERef> }; - * }} powers + * @param {BootDevices & BootstrapSpace} powers */ export const makeBridgeManager = async ({ consume: { loadCriticalVat }, @@ -345,9 +340,7 @@ export const makeBridgeManager = async ({ harden(makeBridgeManager); /** - * @param {BootstrapSpace & { - * consume: { loadCriticalVat: ERef> }; - * }} powers + * @param {BootstrapSpace} powers */ export const makeChainStorage = async ({ consume: { loadCriticalVat, bridgeManager: bridgeManagerP }, @@ -380,9 +373,7 @@ export const makeChainStorage = async ({ }; /** - * @param {BootstrapSpace & { - * consume: { loadCriticalVat: ERef> }; - * }} powers + * @param {BootstrapSpace} powers */ export const produceHighPrioritySendersManager = async ({ consume: { loadCriticalVat, storageBridgeManager: storageBridgeManagerP }, diff --git a/packages/vats/src/core/demoIssuers.js b/packages/vats/src/core/demoIssuers.js index 24fe7c1addc..2a91f1cf1a3 100644 --- a/packages/vats/src/core/demoIssuers.js +++ b/packages/vats/src/core/demoIssuers.js @@ -218,8 +218,7 @@ const provideCoin = async (name, mints) => { }; /** - * @param {BootstrapSpace & { consume: { loadVat: VatLoader } }} powers - * TODO: sync this type with end-user docs? + * @param {BootstrapSpace} powers TODO: sync this type with end-user docs? * * @typedef {{ * issuer: ERef; diff --git a/packages/vats/src/core/types-ambient.d.ts b/packages/vats/src/core/types-ambient.d.ts index e780c051637..0074c75481d 100644 --- a/packages/vats/src/core/types-ambient.d.ts +++ b/packages/vats/src/core/types-ambient.d.ts @@ -109,7 +109,10 @@ type Producer = { }; type VatSourceRef = { bundleName?: string; bundleID?: string }; -type VatLoader = (name: string, sourceRef?: VatSourceRef) => T; +type VatLoader = ( + name: K, + sourceRef?: VatSourceRef, +) => WellKnownVats[K]; /** callback to assign a property onto the `home` object of the client */ type PropertyMaker = (addr: string, flags: string[]) => Record; @@ -434,12 +437,12 @@ type BootstrapSpace = WellKnownSpaces & PromiseSpaceOf< ChainBootstrapSpaceT & { vatAdminSvc: VatAdminSvc; + } & { + loadVat: VatLoader; + loadCriticalVat: VatLoader; }, {}, - { - loadVat: VatLoader; - loadCriticalVat: VatLoader; - } + {} >; type ProvisioningVat = ERef< @@ -507,3 +510,21 @@ type HttpVat = ERef< type UploadsVat = ERef< ReturnType >; + +type WellKnownVats = SwingsetVats & { + bank: BankVat; + board: BoardVat; + bridge: ChainStorageVat; + localchain: LocalChainVat; + ibc: IBCVat; + mints: MintsVat; + network: NetworkVat; + orchestration: ERef< + ReturnType< + typeof import('@agoric/orchestration/src/vat-orchestration.js').buildRootObject + > + >; + priceAuthority: PriceAuthorityVat; + provisioning: ProvisioningVat; + zoe: ERef>; +}; diff --git a/packages/vats/src/proposals/localchain-proposal.js b/packages/vats/src/proposals/localchain-proposal.js index 68c9218ee8d..1fd837d9426 100644 --- a/packages/vats/src/proposals/localchain-proposal.js +++ b/packages/vats/src/proposals/localchain-proposal.js @@ -5,7 +5,6 @@ import { BridgeId as BRIDGE_ID } from '@agoric/internal'; /** * @param {BootstrapPowers & { * consume: { - * loadCriticalVat: VatLoader; * bridgeManager: import('../types').BridgeManager; * localchainBridgeManager: import('../types').ScopedBridgeManager<'vlocalchain'>; * bankManager: Promise; diff --git a/packages/vats/src/proposals/network-proposal.js b/packages/vats/src/proposals/network-proposal.js index c6e185fae5e..b462feb33b5 100644 --- a/packages/vats/src/proposals/network-proposal.js +++ b/packages/vats/src/proposals/network-proposal.js @@ -79,7 +79,6 @@ export const registerNetworkProtocols = async (vats, dibcBridgeManager) => { * - echo port addrees: /ibc-port/custom-echo * * @param {BootstrapPowers & { - * consume: { loadCriticalVat: VatLoader }; * produce: { portAllocator: Producer }; * }} powers * @param {object} options diff --git a/packages/vats/test/vat-bank-integration.test.js b/packages/vats/test/vat-bank-integration.test.js index 1ef20aa8ef5..d2c07b7da64 100644 --- a/packages/vats/test/vat-bank-integration.test.js +++ b/packages/vats/test/vat-bank-integration.test.js @@ -23,9 +23,7 @@ test('mintInitialSupply, addBankAssets bootstrap actions', async t => { // Supply bootstrap prerequisites. const space = /** @type {any} */ (makePromiseSpace(t.log)); /** - * @type {BootstrapPowers & { - * consume: { loadCriticalVat: VatLoader }; - * }} + * @type {BootstrapPowers} */ const { produce, consume } = space; const { agoricNames, agoricNamesAdmin, spaces } = From 777eb21a20fbff3da93d713dc1b95a01fe6ce472 Mon Sep 17 00:00:00 2001 From: Michael FIG Date: Sun, 16 Jun 2024 17:27:43 -0600 Subject: [PATCH 2/2] fix: many typing improvements --- packages/governance/src/types.js | 2 +- .../src/proposals/add-auction.js | 1 - .../src/proposals/econ-behaviors.js | 3 -- .../test/smartWallet/contexts.js | 4 +-- .../psmUpgrade/bootstrap-psm-upgrade.js | 1 - packages/smart-wallet/test/contexts.js | 5 ++- packages/smart-wallet/test/supports.js | 15 ++++++--- .../swingset-liveslots/src/vatDataTypes.d.ts | 9 ++++-- packages/vats/src/bridge.js | 21 ++++++++++++ packages/vats/src/core/basic-behaviors.js | 15 +++++---- packages/vats/src/core/chain-behaviors.js | 24 +++++++------- packages/vats/src/core/demoIssuers.js | 2 +- packages/vats/src/core/types-ambient.d.ts | 32 ++++++++++++------- packages/vats/src/core/utils.js | 1 - .../vats/src/proposals/localchain-proposal.js | 8 +++-- .../vats/src/proposals/network-proposal.js | 9 ++---- .../vats/src/proposals/transfer-proposal.js | 9 ++---- packages/vats/src/types.d.ts | 2 +- packages/vats/src/vat-zoe.js | 2 ++ packages/vats/test/clientBundle.test.js | 13 +++++--- .../vats/test/vat-bank-integration.test.js | 8 +++-- 21 files changed, 112 insertions(+), 74 deletions(-) diff --git a/packages/governance/src/types.js b/packages/governance/src/types.js index 023b6af0907..6cd1b20aeba 100644 --- a/packages/governance/src/types.js +++ b/packages/governance/src/types.js @@ -732,7 +732,7 @@ export {}; * Akin to StartedInstanceKit but designed for the results of starting governed contracts. Used in bootstrap space. * @property {AdminFacet} adminFacet of the governed contract * @property {LimitedCF} creatorFacet creator-like facet within the governed contract (without the powers the governor needs) - * @property {Guarded>} governorCreatorFacet of the governing contract + * @property {Guarded> | GovernorCreatorFacet} governorCreatorFacet of the governing contract * @property {AdminFacet} governorAdminFacet of the governing contract * @property {Awaited>['publicFacet']} publicFacet * @property {Instance} instance diff --git a/packages/inter-protocol/src/proposals/add-auction.js b/packages/inter-protocol/src/proposals/add-auction.js index 7616e8aac56..38657e53ef2 100644 --- a/packages/inter-protocol/src/proposals/add-auction.js +++ b/packages/inter-protocol/src/proposals/add-auction.js @@ -129,7 +129,6 @@ export const addAuction = async ({ ); newAuctioneerKit.resolve( - // @ts-expect-error XXX governance types harden({ label: 'auctioneer', creatorFacet: governedCreatorFacet, diff --git a/packages/inter-protocol/src/proposals/econ-behaviors.js b/packages/inter-protocol/src/proposals/econ-behaviors.js index 18fff54f76d..9b58897e6c9 100644 --- a/packages/inter-protocol/src/proposals/econ-behaviors.js +++ b/packages/inter-protocol/src/proposals/econ-behaviors.js @@ -164,7 +164,6 @@ export const setupReserve = async ({ ]); reserveKit.resolve( - // @ts-expect-error XXX harden({ label: 'AssetReserve', instance, @@ -349,7 +348,6 @@ export const startVaultFactory = async ( ); vaultFactoryKit.resolve( - // @ts-expect-error XXX harden({ label: 'VaultFactory', creatorFacet: vaultFactoryCreator, @@ -624,7 +622,6 @@ export const startAuctioneer = async ( ]); auctioneerKit.resolve( - // @ts-expect-error XXX harden({ label: 'auctioneer', creatorFacet: governedCreatorFacet, diff --git a/packages/inter-protocol/test/smartWallet/contexts.js b/packages/inter-protocol/test/smartWallet/contexts.js index 62c7c62e12d..fb0872219f0 100644 --- a/packages/inter-protocol/test/smartWallet/contexts.js +++ b/packages/inter-protocol/test/smartWallet/contexts.js @@ -10,6 +10,7 @@ import { import { makeHeapZone } from '@agoric/zone'; import { E } from '@endo/far'; import path from 'path'; +import { makeScopedBridge } from '@agoric/vats'; import { oracleBrandFeedName } from '../../src/proposals/utils.js'; import { createPriceFeed } from '../../src/proposals/price-feed-proposal.js'; import { withAmountUtils } from '../supports.js'; @@ -108,9 +109,8 @@ export const makeDefaultTestContext = async (t, makeSpace) => { * @type {undefined * | import('@agoric/vats').ScopedBridgeManager<'wallet'>} */ - // @ts-expect-error XXX EProxy const walletBridgeManager = await (bridgeManager && - E(bridgeManager).register(BridgeId.WALLET)); + makeScopedBridge(bridgeManager, BridgeId.WALLET)); const walletFactory = await E(zoe).startInstance( installation, {}, diff --git a/packages/inter-protocol/test/swingsetTests/psmUpgrade/bootstrap-psm-upgrade.js b/packages/inter-protocol/test/swingsetTests/psmUpgrade/bootstrap-psm-upgrade.js index 2ac25fb7277..cc81868644e 100644 --- a/packages/inter-protocol/test/swingsetTests/psmUpgrade/bootstrap-psm-upgrade.js +++ b/packages/inter-protocol/test/swingsetTests/psmUpgrade/bootstrap-psm-upgrade.js @@ -131,7 +131,6 @@ export const buildRootObject = async () => { * @param {any} devices */ bootstrap: async (vats, devices) => { - // @ts-expect-error XXX adminNode vatAdmin = await E(vats.vatAdmin).createVatAdminService(devices.vatAdmin); ({ feeMintAccess, zoeService } = await E(vats.zoe).buildZoe( vatAdmin, diff --git a/packages/smart-wallet/test/contexts.js b/packages/smart-wallet/test/contexts.js index a5e67942439..0afb7e22b49 100644 --- a/packages/smart-wallet/test/contexts.js +++ b/packages/smart-wallet/test/contexts.js @@ -3,6 +3,7 @@ import { unsafeMakeBundleCache } from '@agoric/swingset-vat/tools/bundleTool.js' import { makeStorageNodeChild } from '@agoric/internal/src/lib-chainStorage.js'; import { E } from '@endo/far'; import path from 'path'; +import { makeScopedBridge } from '@agoric/vats'; import { withAmountUtils } from './supports.js'; /** @@ -38,10 +39,8 @@ export const makeDefaultTestContext = async (t, makeSpace) => { 'anyAddress', ); const bridgeManager = await consume.bridgeManager; - /** @type {import('@agoric/vats').ScopedBridgeManager<'wallet'>} */ - // @ts-expect-error XXX generics through EProxy const walletBridgeManager = await (bridgeManager && - E(bridgeManager).register(BridgeId.WALLET)); + makeScopedBridge(bridgeManager, BridgeId.WALLET)); const walletFactory = await E(zoe).startInstance( installation, {}, diff --git a/packages/smart-wallet/test/supports.js b/packages/smart-wallet/test/supports.js index 3d22cf589db..f929e42831a 100644 --- a/packages/smart-wallet/test/supports.js +++ b/packages/smart-wallet/test/supports.js @@ -100,7 +100,12 @@ const makeFakeBridgeManager = () => export const makeMockTestSpace = async log => { const space = /** @type {any} */ (makePromiseSpace(log)); /** - * @type {BootstrapPowers} + * @type {BootstrapPowers & { + * produce: { + * loadVat: Producer; + * loadCriticalVat: Producer; + * }; + * }} */ const { consume, produce } = space; const { agoricNames, agoricNamesAdmin, spaces } = @@ -112,13 +117,15 @@ export const makeMockTestSpace = async log => { produce.zoe.resolve(zoe); produce.feeMintAccess.resolve(feeMintAccessP); - const vatLoader = name => { + /** @type {VatLoader<'mints' | 'board'>} */ + const vatLoader = async name => { + /** @typedef {Awaited} ReturnedVat */ switch (name) { case 'mints': - return mintsRoot(); + return /** @type {ReturnedVat} */ (mintsRoot()); case 'board': { const baggage = makeScalarBigMapStore('baggage'); - return boardRoot({}, {}, baggage); + return /** @type {ReturnedVat} */ (boardRoot({}, {}, baggage)); } default: throw Error('unknown loadVat name'); diff --git a/packages/swingset-liveslots/src/vatDataTypes.d.ts b/packages/swingset-liveslots/src/vatDataTypes.d.ts index 2e822b3a912..91cd954c784 100644 --- a/packages/swingset-liveslots/src/vatDataTypes.d.ts +++ b/packages/swingset-liveslots/src/vatDataTypes.d.ts @@ -14,6 +14,7 @@ import type { } from '@agoric/store'; import type { Amplify, IsInstance, ReceivePower, StateShape } from '@endo/exo'; import type { RemotableObject } from '@endo/pass-style'; +import type { RemotableBrand } from '@endo/eventual-send'; import type { InterfaceGuard, Pattern } from '@endo/patterns'; import type { makeWatchedPromiseManager } from './watchedPromises.js'; @@ -38,9 +39,13 @@ type OmitFirstArg = F extends (x: any, ...args: infer P) => infer R ? (...args: P) => R : never; -export type KindFacet = RemotableObject & { +// The type of a passable local object with methods. +// An internal helper to avoid having to repeat `O`. +type PrimaryRemotable = O & RemotableObject & RemotableBrand<{}, O>; + +export type KindFacet = PrimaryRemotable<{ [K in keyof O]: OmitFirstArg; // omit the 'context' parameter -}; +}>; export type KindFacets = { [FacetKey in keyof B]: KindFacet; diff --git a/packages/vats/src/bridge.js b/packages/vats/src/bridge.js index b6cacd0bb2c..4d52963e2d3 100644 --- a/packages/vats/src/bridge.js +++ b/packages/vats/src/bridge.js @@ -3,6 +3,27 @@ import { E } from '@endo/far'; const { Fail, details: X } = assert; +/** + * Helper to type the registered scoped bridge correctly. + * + * FIXME: This is needed because `register` is not an async function, so + * `E(x).register` needs to reconstruct its return value as a Promise, which + * loses the function's genericity. If `register` was async, we could use its + * type directly, and it would remain generic. + * + * @template {import('@agoric/internal').BridgeIdValue} BridgeId + * @param {ERef} bridgeManager + * @param {BridgeId} bridgeIdValue + * @param {import('@agoric/internal').Remote< + * import('./types.js').BridgeHandler + * >} [handler] + * @returns {Promise>} + */ +export const makeScopedBridge = (bridgeManager, bridgeIdValue, handler) => + /** @type {Promise>} */ ( + E(bridgeManager).register(bridgeIdValue, handler) + ); + export const BridgeHandlerI = M.interface('BridgeHandler', { fromBridge: M.call(M.any()).returns(M.promise()), }); diff --git a/packages/vats/src/core/basic-behaviors.js b/packages/vats/src/core/basic-behaviors.js index 18434e61548..a344d42c96b 100644 --- a/packages/vats/src/core/basic-behaviors.js +++ b/packages/vats/src/core/basic-behaviors.js @@ -16,6 +16,7 @@ import { Fail, NonNullish } from '@agoric/assert'; import { makeNameHubKit } from '../nameHub.js'; import { PowerFlags } from '../walletFlags.js'; import { feeIssuerConfig, makeMyAddressNameAdminKit } from './utils.js'; +import { makeScopedBridge } from '../bridge.js'; /** @import {GovernableStartFn, GovernanceFacetKit} from '@agoric/governance/src/types.js'; */ @@ -52,7 +53,12 @@ const bootMsgEx = { /** @typedef {MapStore} VatStore */ /** - * @param {BootstrapPowers & {}} powers + * @param {BootstrapPowers & { + * produce: { + * loadVat: Producer; + * loadCriticalVat: Producer; + * }; + * }} powers * @import {CreateVatResults} from '@agoric/swingset-vat' * as from createVatByName */ @@ -65,7 +71,6 @@ export const makeVatsFromBundles = async ({ // NOTE: we rely on multiple createVatAdminService calls // to return cooperating services. const svc = E(vats.vatAdmin).createVatAdminService(devices.vatAdmin); - // @ts-expect-error XXX vatAdminSvc.resolve(svc); const durableStore = await vatStore; @@ -80,7 +85,6 @@ export const makeVatsFromBundles = async ({ if (bundleName) { console.info(`createVatByName(${bundleName})`); /** @type {Promise} */ - // @ts-expect-error XXX const vatInfo = E(svc).createVatByName(bundleName, { ...defaultVatCreationOptions, name: vatName, @@ -91,7 +95,6 @@ export const makeVatsFromBundles = async ({ assert(bundleID); const bcap = await E(svc).getBundleCap(bundleID); /** @type {Promise} */ - // @ts-expect-error XXX const vatInfo = E(svc).createVat(bcap, { ...defaultVatCreationOptions, name: vatName, @@ -647,10 +650,8 @@ export const addBankAssets = async ({ const assetAdmin = E(agoricNamesAdmin).lookupAdmin('vbankAsset'); const bridgeManager = await bridgeManagerP; - /** @type {import('../types.js').ScopedBridgeManager<'bank'> | undefined} */ - // @ts-expect-error XXX EProxy const bankBridgeManager = - bridgeManager && E(bridgeManager).register(BridgeId.BANK); + bridgeManager && makeScopedBridge(bridgeManager, BridgeId.BANK); const bankMgr = await E(E(loadCriticalVat)('bank')).makeBankManager( bankBridgeManager, assetAdmin, diff --git a/packages/vats/src/core/chain-behaviors.js b/packages/vats/src/core/chain-behaviors.js index 2c1eb9ba3a9..71ab4246705 100644 --- a/packages/vats/src/core/chain-behaviors.js +++ b/packages/vats/src/core/chain-behaviors.js @@ -16,6 +16,7 @@ import { makePromiseKit } from '@endo/promise-kit'; import { PowerFlags } from '../walletFlags.js'; import { BASIC_BOOTSTRAP_PERMITS } from './basic-behaviors.js'; import { agoricNamesReserved, callProperties, extractPowers } from './utils.js'; +import { makeScopedBridge } from '../bridge.js'; const { Fail } = assert; const { keys } = Object; @@ -104,7 +105,7 @@ export const bridgeCoreEval = async allPowers => { // Not running with a bridge. return; } - await E(bridgeManager).register(BRIDGE_ID.CORE, handler); + await makeScopedBridge(bridgeManager, BRIDGE_ID.CORE, handler); }; harden(bridgeCoreEval); @@ -327,15 +328,14 @@ export const makeBridgeManager = async ({ const bridgeManager = E(vat).provideManagerForBridge(bridge); bridgeManagerP.resolve(bridgeManager); provisionBridgeManager.resolve( - // @ts-expect-error XXX EProxy - E(bridgeManager).register(BRIDGE_ID.PROVISION), + makeScopedBridge(bridgeManager, BRIDGE_ID.PROVISION), ); provisionWalletBridgeManager.resolve( - // @ts-expect-error XXX EProxy - E(bridgeManager).register(BRIDGE_ID.PROVISION_SMART_WALLET), + makeScopedBridge(bridgeManager, BRIDGE_ID.PROVISION_SMART_WALLET), + ); + walletBridgeManager.resolve( + makeScopedBridge(bridgeManager, BRIDGE_ID.WALLET), ); - // @ts-expect-error XXX EProxy - walletBridgeManager.resolve(E(bridgeManager).register(BRIDGE_ID.WALLET)); }; harden(makeBridgeManager); @@ -353,14 +353,14 @@ export const makeChainStorage = async ({ if (!bridgeManager) { console.warn('Cannot support chainStorage without an actual chain.'); chainStorageP.resolve(null); - // @ts-expect-error expects value or undefined - storageBridgeManagerP.resolve(null); + storageBridgeManagerP.resolve(undefined); return; } - /** @type {import('../types.js').ScopedBridgeManager<'storage'>} */ - // @ts-expect-error XXX EProxy - const storageBridgeManager = E(bridgeManager).register(BRIDGE_ID.STORAGE); + const storageBridgeManager = makeScopedBridge( + bridgeManager, + BRIDGE_ID.STORAGE, + ); storageBridgeManagerP.resolve(storageBridgeManager); const vat = E(loadCriticalVat)('bridge'); diff --git a/packages/vats/src/core/demoIssuers.js b/packages/vats/src/core/demoIssuers.js index 2a91f1cf1a3..b8476f0219f 100644 --- a/packages/vats/src/core/demoIssuers.js +++ b/packages/vats/src/core/demoIssuers.js @@ -209,7 +209,7 @@ const mintRunPayment = async ( /** * @param {string} name - * @param {MintsVat} mints + * @param {ERef} mints */ const provideCoin = async (name, mints) => { return E(mints).provideIssuerKit(name, AssetKind.NAT, { diff --git a/packages/vats/src/core/types-ambient.d.ts b/packages/vats/src/core/types-ambient.d.ts index 0074c75481d..74359b00ac7 100644 --- a/packages/vats/src/core/types-ambient.d.ts +++ b/packages/vats/src/core/types-ambient.d.ts @@ -109,10 +109,10 @@ type Producer = { }; type VatSourceRef = { bundleName?: string; bundleID?: string }; -type VatLoader = ( - name: K, +type VatLoader = ( + name: N, sourceRef?: VatSourceRef, -) => WellKnownVats[K]; +) => Promise>; /** callback to assign a property onto the `home` object of the client */ type PropertyMaker = (addr: string, flags: string[]) => Record; @@ -437,14 +437,22 @@ type BootstrapSpace = WellKnownSpaces & PromiseSpaceOf< ChainBootstrapSpaceT & { vatAdminSvc: VatAdminSvc; - } & { + }, + { loadVat: VatLoader; loadCriticalVat: VatLoader; }, - {}, {} >; +type LocalChainVat = ERef< + ReturnType +>; + +type TransferVat = ERef< + ReturnType +>; + type ProvisioningVat = ERef< ReturnType >; @@ -468,6 +476,9 @@ type NamedVatPowers = { }>; }; +type OrchestrationVat = ERef; +type ZoeVat = ERef; + type RemoteIssuerKit = { mint: ERef; issuer: ERef; @@ -515,16 +526,13 @@ type WellKnownVats = SwingsetVats & { bank: BankVat; board: BoardVat; bridge: ChainStorageVat; - localchain: LocalChainVat; ibc: IBCVat; + localchain: LocalChainVat; mints: MintsVat; network: NetworkVat; - orchestration: ERef< - ReturnType< - typeof import('@agoric/orchestration/src/vat-orchestration.js').buildRootObject - > - >; + orchestration: OrchestrationVat; priceAuthority: PriceAuthorityVat; provisioning: ProvisioningVat; - zoe: ERef>; + transfer: TransferVat; + zoe: ZoeVat; }; diff --git a/packages/vats/src/core/utils.js b/packages/vats/src/core/utils.js index 4e3539622c4..25aee277603 100644 --- a/packages/vats/src/core/utils.js +++ b/packages/vats/src/core/utils.js @@ -363,7 +363,6 @@ export const makeVatSpace = ( { get: (_target, name, _rx) => { assert.typeof(name, 'string'); - // @ts-expect-error XXX return provideAsync(name, createVatByName).then(vat => { if (!durableStore.has(name)) { durableStore.init(name, vat); diff --git a/packages/vats/src/proposals/localchain-proposal.js b/packages/vats/src/proposals/localchain-proposal.js index 1fd837d9426..947c427b190 100644 --- a/packages/vats/src/proposals/localchain-proposal.js +++ b/packages/vats/src/proposals/localchain-proposal.js @@ -1,6 +1,7 @@ // @ts-check import { E } from '@endo/far'; import { BridgeId as BRIDGE_ID } from '@agoric/internal'; +import { makeScopedBridge } from '../bridge.js'; /** * @param {BootstrapPowers & { @@ -57,9 +58,10 @@ export const setupLocalChainVat = async ( /** @type {import('../types').ScopedBridgeManager<'vlocalchain'>} */ let scopedManager; try { - /** @type {import('../types.js').ScopedBridgeManager<'vlocalchain'>} */ - // @ts-expect-error XXX EProxy - scopedManager = await E(bridgeManager).register(BRIDGE_ID.VLOCALCHAIN); + scopedManager = await makeScopedBridge( + bridgeManager, + BRIDGE_ID.VLOCALCHAIN, + ); localchainBridgeManager.reset(); localchainBridgeManager.resolve(scopedManager); } catch (e) { diff --git a/packages/vats/src/proposals/network-proposal.js b/packages/vats/src/proposals/network-proposal.js index b462feb33b5..c5aa8afdaa2 100644 --- a/packages/vats/src/proposals/network-proposal.js +++ b/packages/vats/src/proposals/network-proposal.js @@ -10,6 +10,7 @@ import { makeScalarBigMapStore } from '@agoric/vat-data'; // Heap-based vow resolution is used for this module because the // bootstrap vat can't yet be upgraded. import { heapVowTools } from '@agoric/vow/vat.js'; +import { makeScopedBridge } from '../bridge.js'; const { when } = heapVowTools; @@ -83,10 +84,6 @@ export const registerNetworkProtocols = async (vats, dibcBridgeManager) => { * }} powers * @param {object} options * @param {{ networkRef: VatSourceRef; ibcRef: VatSourceRef }} options.options - * // TODO: why doesn't overloading VatLoader work??? - * - * @typedef {((name: 'network') => NetworkVat) & ((name: 'ibc') => IBCVat)} VatLoader2 - * * * @typedef {{ * network: ERef; @@ -132,10 +129,8 @@ export const setupNetworkProtocols = async ( const allocator = await portAllocatorP; const bridgeManager = await bridgeManagerP; - /** @type {import('../types.js').ScopedBridgeManager<'dibc'> | undefined} */ - // @ts-expect-error XXX EProxy const dibcBridgeManager = - bridgeManager && E(bridgeManager).register(BRIDGE_ID.DIBC); + bridgeManager && makeScopedBridge(bridgeManager, BRIDGE_ID.DIBC); // The Interchain Account (ICA) Controller must be bound to a port that starts // with 'icacontroller', so we provide one such port to each client. diff --git a/packages/vats/src/proposals/transfer-proposal.js b/packages/vats/src/proposals/transfer-proposal.js index 594bc3297ad..25bdfaa8877 100644 --- a/packages/vats/src/proposals/transfer-proposal.js +++ b/packages/vats/src/proposals/transfer-proposal.js @@ -1,11 +1,11 @@ // @ts-check import { E } from '@endo/far'; import { BridgeId as BRIDGE_ID, VTRANSFER_IBC_EVENT } from '@agoric/internal'; +import { makeScopedBridge } from '../bridge.js'; /** * @param {BootstrapPowers & { * consume: { - * loadCriticalVat: VatLoader; * bridgeManager: import('../types').BridgeManager; * vtransferBridgeManager: import('../types').ScopedBridgeManager<'vtransfer'>; * }; @@ -17,10 +17,6 @@ import { BridgeId as BRIDGE_ID, VTRANSFER_IBC_EVENT } from '@agoric/internal'; * }} powers * @param {object} options * @param {{ transferRef: VatSourceRef }} options.options - * - * @typedef {{ - * transfer: ERef; - * }} TransferVats */ export const setupTransferMiddleware = async ( { @@ -44,7 +40,6 @@ export const setupTransferMiddleware = async ( } const { transferRef } = options.options; - /** @type {TransferVats} */ const vats = { transfer: E(loadCriticalVat)('transfer', transferRef), }; @@ -73,7 +68,7 @@ export const setupTransferMiddleware = async ( /** @type {Awaited>} */ let bridgeTargetKit; try { - const vtransferBridge = await E(bridgeManager).register(vtransferID); + const vtransferBridge = await makeScopedBridge(bridgeManager, vtransferID); produceVtransferBridgeManager.reset(); produceVtransferBridgeManager.resolve(vtransferBridge); bridgeTargetKit = await provideBridgeTargetKit(vtransferBridge); diff --git a/packages/vats/src/types.d.ts b/packages/vats/src/types.d.ts index f8c9dde5570..fba8b1d161d 100644 --- a/packages/vats/src/types.d.ts +++ b/packages/vats/src/types.d.ts @@ -114,7 +114,7 @@ export type ScopedBridgeManager = Guarded<{ export type BridgeManager = { register: ( bridgeId: BridgeId, - handler?: Remote, + handler?: Remote, ) => ScopedBridgeManager; }; diff --git a/packages/vats/src/vat-zoe.js b/packages/vats/src/vat-zoe.js index 6ee24cc21c0..f37422e4853 100644 --- a/packages/vats/src/vat-zoe.js +++ b/packages/vats/src/vat-zoe.js @@ -52,3 +52,5 @@ export function buildRootObject(vatPowers, _vatParams, zoeBaggage) { getZoeConfigFacet: () => zoeConfigFacet, }); } + +/** @typedef {ReturnType} ZoeVat */ diff --git a/packages/vats/test/clientBundle.test.js b/packages/vats/test/clientBundle.test.js index fcc066c55c1..4bf665efeb5 100644 --- a/packages/vats/test/clientBundle.test.js +++ b/packages/vats/test/clientBundle.test.js @@ -34,7 +34,10 @@ test('connectFaucet produces payments', async t => { /** * @type {BootstrapPowers & * DemoFaucetPowers & { - * consume: { loadVat: LoadVat; loadCriticalVat: LoadVat }; + * produce: { + * loadVat: Producer; + * loadCriticalVat: Producer; + * }; * }} */ const { consume, produce } = space; @@ -54,13 +57,15 @@ test('connectFaucet produces payments', async t => { produce.vatAdminSvc.resolve(vatAdminSvc); - const vatLoader = name => { + /** @type {VatLoader<'mints' | 'board'>} */ + const vatLoader = async (name, _sourceRef) => { + /** @typedef {Awaited} ReturnedVat */ switch (name) { case 'mints': - return mintsRoot(); + return /** @type {ReturnedVat} */ (mintsRoot()); case 'board': { const baggage = makeScalarBigMapStore('baggage'); - return boardRoot({}, {}, baggage); + return /** @type {ReturnedVat} */ (boardRoot({}, {}, baggage)); } default: throw Error('unknown loadVat name'); diff --git a/packages/vats/test/vat-bank-integration.test.js b/packages/vats/test/vat-bank-integration.test.js index d2c07b7da64..33cfe964744 100644 --- a/packages/vats/test/vat-bank-integration.test.js +++ b/packages/vats/test/vat-bank-integration.test.js @@ -23,7 +23,9 @@ test('mintInitialSupply, addBankAssets bootstrap actions', async t => { // Supply bootstrap prerequisites. const space = /** @type {any} */ (makePromiseSpace(t.log)); /** - * @type {BootstrapPowers} + * @type {BootstrapPowers & { + * produce: { loadCriticalVat: Producer }; + * }} */ const { produce, consume } = space; const { agoricNames, agoricNamesAdmin, spaces } = @@ -85,13 +87,15 @@ test('mintInitialSupply, addBankAssets bootstrap actions', async t => { 'initialSupply of 50 RUN', ); + /** @type {VatLoader<'bank'>} */ const loadCriticalVat = async name => { assert.equal(name, 'bank'); - return E(buildRootObject)( + const vatP = E(buildRootObject)( null, null, makeScalarMapStore('addAssets baggage'), ); + return /** @type {Awaited} */ (vatP); }; produce.loadCriticalVat.resolve(loadCriticalVat); produce.bridgeManager.resolve(undefined);