diff --git a/packages/inter-protocol/src/price/fluxAggregator.contract.js b/packages/inter-protocol/src/price/fluxAggregator.contract.js index 52a73a0132c3..e72c7b1aabd5 100644 --- a/packages/inter-protocol/src/price/fluxAggregator.contract.js +++ b/packages/inter-protocol/src/price/fluxAggregator.contract.js @@ -1,6 +1,8 @@ import { AssetKind, makeIssuerKit } from '@agoric/ertp'; +import { handleParamGovernance } from '@agoric/governance'; import { assertAllDefined } from '@agoric/internal'; import { E } from '@endo/eventual-send'; +import { Far } from '@endo/marshal'; import { provideFluxAggregator } from './fluxAggregator.js'; /** @@ -20,6 +22,7 @@ import { provideFluxAggregator } from './fluxAggregator.js'; * unitAmountIn?: Amount<'nat'>, * }>} zcf * @param {{ + * initialPoserInvitation: Invitation, * marshaller: Marshaller, * quoteMint?: ERef>, * storageNode: ERef, @@ -40,8 +43,12 @@ export const start = async (zcf, privateArgs, baggage) => { mint: quoteMint, }; - const { marshaller, storageNode: storageNodeP } = privateArgs; - assertAllDefined({ marshaller, storageNodeP }); + const { + initialPoserInvitation, + marshaller, + storageNode: storageNodeP, + } = privateArgs; + assertAllDefined({ initialPoserInvitation, marshaller, storageNodeP }); const timer = await timerP; const storageNode = await storageNodeP; @@ -55,8 +62,24 @@ export const start = async (zcf, privateArgs, baggage) => { marshaller, ); + const { makeGovernorFacet } = await handleParamGovernance( + // @ts-expect-error FIXME include Governance params + zcf, + initialPoserInvitation, + { + // No governed parameters. Governance just for API methods. + }, + storageNode, + marshaller, + ); + + const governedApis = { + initOracle: fa.creatorFacet.initOracle, + }; + + const governorFacet = makeGovernorFacet(fa.creatorFacet, governedApis); return harden({ - creatorFacet: fa.creatorFacet, + creatorFacet: governorFacet, publicFacet: fa.publicFacet, }); }; diff --git a/packages/inter-protocol/test/test-priceAggregatorChainlink.js b/packages/inter-protocol/test/test-priceAggregatorChainlink.js index 4be2e86d4482..312540bf5ab4 100644 --- a/packages/inter-protocol/test/test-priceAggregatorChainlink.js +++ b/packages/inter-protocol/test/test-priceAggregatorChainlink.js @@ -8,6 +8,7 @@ import bundleSource from '@endo/bundle-source'; import { E } from '@endo/eventual-send'; import { Far } from '@endo/marshal'; import { makeIssuerKit, AssetKind } from '@agoric/ertp'; +import { setUpGovernedContract } from '@agoric/governance/tools/puppetGovernance.js'; import { eventLoopIteration, @@ -26,7 +27,11 @@ const test = unknownTest; const filename = new URL(import.meta.url).pathname; const dirname = path.dirname(filename); -const aggregatorPath = `${dirname}/../src/price/fluxAggregator.contract.js`; +// Pack the contracts. +/** @type {EndoZipBase64Bundle} */ +const aggregatorBundle = await bundleSource( + `${dirname}/../src/price/fluxAggregator.contract.js`, +); const defaultConfig = { maxSubmissionCount: 1000, @@ -43,9 +48,6 @@ const makeContext = async () => { const { admin, vatAdminState } = makeFakeVatAdmin(); const { zoeService: zoe } = makeZoeKit(admin); - // Pack the contracts. - const aggregatorBundle = await bundleSource(aggregatorPath); - // Install the contract on Zoe, getting an installation. We can // use this installation to look up the code we installed. Outside // of tests, we can also send the installation to someone @@ -58,6 +60,9 @@ const makeContext = async () => { const link = makeIssuerKit('$LINK', AssetKind.NAT); const usd = makeIssuerKit('$USD', AssetKind.NAT); + /** + * @param {Record} config + */ async function makeChainlinkAggregator(config) { const { maxSubmissionCount, @@ -75,9 +80,10 @@ const makeContext = async () => { const timer = buildManualTimer(() => {}); - const aggregator = await E(zoe).startInstance( + const { governorFacets } = await setUpGovernedContract( + zoe, aggregatorInstallation, - undefined, + timer, { timer, brandIn: link.brand, @@ -88,13 +94,20 @@ const makeContext = async () => { timeout, minSubmissionValue, maxSubmissionValue, + governedApis: ['initOracle'], }, { marshaller, storageNode: E(storageNode).makeChildNode('LINK-USD_price_feed'), }, ); - return { ...aggregator, mockStorageRoot }; + + return { + governor: governorFacets.creatorFacet, + public: governorFacets.publicFacet, + instance: governorFacets.instance, + mockStorageRoot, + }; } return { makeChainlinkAggregator, zoe }; @@ -112,14 +125,20 @@ test('basic', async t => { // @ts-expect-error cast const { timer: oracleTimer } = await E(zoe).getTerms(aggregator.instance); - const pricePushAdminA = await E(aggregator.creatorFacet).initOracle( - 'agorice1priceOracleA', + /** @type {import('../src/price/priceOracleAdmin.js').OracleAdmin} */ + // @ts-expect-error cast + const pricePushAdminA = await E( + aggregator.governor.invokeAPI('initOracle', ['agorice1priceOracleA']), ); - const pricePushAdminB = await E(aggregator.creatorFacet).initOracle( - 'agorice1priceOracleB', + /** @type {import('../src/price/priceOracleAdmin.js').OracleAdmin} */ + // @ts-expect-error cast + const pricePushAdminB = await E( + aggregator.governor.invokeAPI('initOracle', ['agorice1priceOracleB']), ); - const pricePushAdminC = await E(aggregator.creatorFacet).initOracle( - 'agorice1priceOracleC', + /** @type {import('../src/price/priceOracleAdmin.js').OracleAdmin} */ + // @ts-expect-error cast + const pricePushAdminC = await E( + aggregator.governor.invokeAPI('initOracle', ['agorice1priceOracleC']), ); // ----- round 1: basic consensus