diff --git a/packages/builders/scripts/orchestration/init-stakeAtom.js b/packages/builders/scripts/orchestration/init-stakeAtom.js index 68166a7601d..94f5ab4aea2 100644 --- a/packages/builders/scripts/orchestration/init-stakeAtom.js +++ b/packages/builders/scripts/orchestration/init-stakeAtom.js @@ -9,6 +9,7 @@ export const defaultProposalBuilder = async ( hostConnectionId = 'connection-1', controllerConnectionId = 'connection-0', bondDenom = 'uatom', + icqEnabled = true, } = options; return harden({ sourceSpec: '@agoric/orchestration/src/proposals/start-stakeAtom.js', @@ -23,6 +24,7 @@ export const defaultProposalBuilder = async ( hostConnectionId, controllerConnectionId, bondDenom, + icqEnabled, }, ], }); diff --git a/packages/orchestration/src/examples/stakeIca.contract.js b/packages/orchestration/src/examples/stakeIca.contract.js index 8f4562220a4..cc0a6731067 100644 --- a/packages/orchestration/src/examples/stakeIca.contract.js +++ b/packages/orchestration/src/examples/stakeIca.contract.js @@ -24,6 +24,7 @@ export const meta = harden({ hostConnectionId: M.string(), controllerConnectionId: M.string(), bondDenom: M.string(), + icqEnabled: M.boolean(), }, privateArgsShape: { orchestration: M.remotable('orchestration'), @@ -40,6 +41,7 @@ export const privateArgsShape = meta.privateArgsShape; * hostConnectionId: IBCConnectionID; * controllerConnectionId: IBCConnectionID; * bondDenom: string; + * icqEnabled: boolean; * }} StakeIcaTerms */ @@ -54,8 +56,13 @@ export const privateArgsShape = meta.privateArgsShape; * @param {Baggage} baggage */ export const start = async (zcf, privateArgs, baggage) => { - const { chainId, hostConnectionId, controllerConnectionId, bondDenom } = - zcf.getTerms(); + const { + chainId, + hostConnectionId, + controllerConnectionId, + bondDenom, + icqEnabled, + } = zcf.getTerms(); const { orchestration, marshaller, storageNode, timer } = privateArgs; const zone = makeDurableZone(baggage); @@ -74,12 +81,11 @@ export const start = async (zcf, privateArgs, baggage) => { hostConnectionId, controllerConnectionId, ); - // TODO https://github.com/Agoric/agoric-sdk/issues/9326 - // Should not fail if host does not have `async-icq` module; - // communicate to OrchestrationAccount that it can't send queries - const icqConnection = await E(orchestration).provideICQConnection( - controllerConnectionId, - ); + // TODO permissionless queries https://github.com/Agoric/agoric-sdk/issues/9326 + const icqConnection = icqEnabled + ? await E(orchestration).provideICQConnection(controllerConnectionId) + : undefined; + const accountAddress = await E(account).getAddress(); trace('account address', accountAddress); const holder = makeCosmosOrchestrationAccount(accountAddress, bondDenom, { diff --git a/packages/orchestration/src/exos/cosmosOrchestrationAccount.js b/packages/orchestration/src/exos/cosmosOrchestrationAccount.js index f1c10cb24ac..6ef7ea2ec8a 100644 --- a/packages/orchestration/src/exos/cosmosOrchestrationAccount.js +++ b/packages/orchestration/src/exos/cosmosOrchestrationAccount.js @@ -60,7 +60,7 @@ const { Fail } = assert; * topicKit: RecorderKit; * account: IcaAccount; * chainAddress: ChainAddress; - * icqConnection: ICQConnection; + * icqConnection: ICQConnection | undefined; * bondDenom: string; * timer: Remote; * }} State @@ -149,7 +149,7 @@ export const prepareCosmosOrchestrationAccountKit = ( * @param {object} io * @param {IcaAccount} io.account * @param {Remote} io.storageNode - * @param {ICQConnection} io.icqConnection + * @param {ICQConnection | undefined} io.icqConnection * @param {Remote} io.timer * @returns {State} */ @@ -363,6 +363,7 @@ export const prepareCosmosOrchestrationAccountKit = ( */ async getBalance(denom) { const { chainAddress, icqConnection } = this.state; + if (!icqConnection) throw Error('Queries not enabled.'); // TODO #9211 lookup denom from brand assert.typeof(denom, 'string'); diff --git a/packages/orchestration/src/proposals/start-stakeAtom.js b/packages/orchestration/src/proposals/start-stakeAtom.js index 228b4ccc9bc..2648f810beb 100644 --- a/packages/orchestration/src/proposals/start-stakeAtom.js +++ b/packages/orchestration/src/proposals/start-stakeAtom.js @@ -65,6 +65,8 @@ export const startStakeAtom = async ({ hostConnectionId: connectionInfo.id, controllerConnectionId: connectionInfo.counterparty.connection_id, bondDenom: cosmoshub.stakingTokens[0].denom, + // @ts-expect-error icqEnabled exists on CosmosChainInfo type + icqEnabled: !!cosmoshub.icqEnabled, }, privateArgs: { orchestration: await orchestration, diff --git a/packages/orchestration/test/examples/stake-atom.contract.test.ts b/packages/orchestration/test/examples/stake-atom.contract.test.ts index 31f8478b03e..3dea9945d04 100644 --- a/packages/orchestration/test/examples/stake-atom.contract.test.ts +++ b/packages/orchestration/test/examples/stake-atom.contract.test.ts @@ -1,11 +1,11 @@ import { test } from '@agoric/zoe/tools/prepare-test-env-ava.js'; -import { AmountMath } from '@agoric/ertp'; import { setUpZoeForTest } from '@agoric/zoe/tools/setup-zoe.js'; import { E } from '@endo/far'; import path from 'path'; import type { Installation } from '@agoric/zoe/src/zoeService/utils.js'; import { commonSetup } from '../supports.js'; +import { type StakeAtomTerms } from '../../src/examples/stakeAtom.contract.js'; const dirname = path.dirname(new URL(import.meta.url).pathname); @@ -18,7 +18,13 @@ const startContract = async ({ timer, marshaller, storage, - bld, + issuerKeywordRecord, + terms = { + hostConnectionId: 'connection-1', + controllerConnectionId: 'connection-2', + bondDenom: 'uatom', + icqEnabled: false, + } as StakeAtomTerms, }) => { const { zoe, bundleAndInstall } = await setUpZoeForTest(); const installation: Installation = @@ -43,21 +49,23 @@ const startContract = async ({ return { publicFacet, zoe }; }; -test('makeAccount, deposit, withdraw', async t => { +test('makeAccount, getAddress, getBalances, getBalance', async t => { const { bootstrap, brands: { ist }, utils, } = await commonSetup(t); - const { publicFacet } = await startContract({ ...bootstrap, bld: ist }); + const { publicFacet } = await startContract({ + ...bootstrap, + issuerKeywordRecord: { In: ist.issuer }, + }); t.log('make an ICA account'); const account = await E(publicFacet).makeAccount(); t.truthy(account, 'account is returned'); - const address = await E(account).getAddress(); - // XXX address.address is weird - // t.regex(address.address, /agoric1/); - t.like(address, { chainId: 'cosmoshub-4', addressEncoding: 'bech32' }); + const chainAddress = await E(account).getAddress(); + // t.regex(address.address, /cosmos1/); + t.like(chainAddress, { chainId: 'cosmoshub-4', addressEncoding: 'bech32' }); t.log('deposit 100 bld to account'); await E(account).deposit(await utils.pourPayment(ist.units(100))); @@ -65,4 +73,8 @@ test('makeAccount, deposit, withdraw', async t => { await t.throwsAsync(E(account).getBalances(), { message: 'not yet implemented', }); + + await t.throwsAsync(E(account).getBalance('uatom'), { + message: 'Queries not enabled.', + }); });