From 984fc9ab6462a06a47f9634a91cf5f92b03b5373 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Wed, 19 Jun 2024 07:05:37 -0700 Subject: [PATCH 01/10] refactor: staking denom --- .../orchestration/src/exos/remote-chain-facade.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/packages/orchestration/src/exos/remote-chain-facade.js b/packages/orchestration/src/exos/remote-chain-facade.js index bcf16cd573e..c8d50d5c50c 100644 --- a/packages/orchestration/src/exos/remote-chain-facade.js +++ b/packages/orchestration/src/exos/remote-chain-facade.js @@ -71,15 +71,11 @@ export const prepareRemoteChainFacade = ( const address = await V(icaAccount).getAddress(); - const [{ denom: bondDenom }] = remoteChainInfo.stakingTokens || [ - { - denom: null, - }, - ]; - if (!bondDenom) { - throw Fail`missing bondDenom`; + const stakingDenom = remoteChainInfo.stakingTokens?.[0]?.denom; + if (!stakingDenom) { + throw Fail`chain info lacks staking denom`; } - return makeCosmosOrchestrationAccount(address, bondDenom, { + return makeCosmosOrchestrationAccount(address, stakingDenom, { account: icaAccount, storageNode, icqConnection: anyVal, From bcb1e899018ab82e0802547b39e0720b7cd95359 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Wed, 19 Jun 2024 07:10:49 -0700 Subject: [PATCH 02/10] chore: XXX -> FIXME for release blockers --- packages/orchestration/src/chain-info.js | 2 +- packages/orchestration/src/examples/sendAnywhere.contract.js | 2 +- packages/orchestration/src/examples/stakeBld.contract.js | 2 +- packages/orchestration/src/exos/chainAccountKit.js | 4 ++-- packages/orchestration/src/service.js | 2 +- packages/orchestration/src/utils/chainHub.js | 2 +- packages/orchestration/src/utils/orc.js | 4 ++-- packages/orchestration/src/utils/start-helper.js | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/orchestration/src/chain-info.js b/packages/orchestration/src/chain-info.js index 90ed61d885f..f387faca34e 100644 --- a/packages/orchestration/src/chain-info.js +++ b/packages/orchestration/src/chain-info.js @@ -10,7 +10,7 @@ import fetchedChainInfo from './fetched-chain-info.js'; const knownChains = /** @satisfies {Record} */ ( harden({ ...fetchedChainInfo, - // XXX does not have useful connections + // FIXME does not have useful connections // UNTIL https://github.com/Agoric/agoric-sdk/issues/9492 agoriclocal: { chainId: 'agoriclocal', diff --git a/packages/orchestration/src/examples/sendAnywhere.contract.js b/packages/orchestration/src/examples/sendAnywhere.contract.js index 6ea16f3c44c..4b6c37982f5 100644 --- a/packages/orchestration/src/examples/sendAnywhere.contract.js +++ b/packages/orchestration/src/examples/sendAnywhere.contract.js @@ -79,7 +79,7 @@ export const start = async (zcf, privateArgs, baggage) => { const { denom } = await findBrandInVBank(amt.brand); const chain = await orch.getChain(chainName); - // XXX ok to use a heap var crossing the membrane scope this way? + // FIXME ok to use a heap var crossing the membrane scope this way? if (!contractAccount) { const agoricChain = await orch.getChain('agoric'); contractAccount = await agoricChain.makeAccount(); diff --git a/packages/orchestration/src/examples/stakeBld.contract.js b/packages/orchestration/src/examples/stakeBld.contract.js index 17fddccf346..c3adbd178fb 100644 --- a/packages/orchestration/src/examples/stakeBld.contract.js +++ b/packages/orchestration/src/examples/stakeBld.contract.js @@ -58,7 +58,7 @@ export const start = async (zcf, privateArgs, baggage) => { async function makeLocalAccountKit() { const account = await V(privateArgs.localchain).makeAccount(); const address = await V(account).getAddress(); - // XXX 'address' is implied by 'account'; use an async maker that get the value itself + // FIXME 'address' is implied by 'account'; use an async maker that get the value itself return makeLocalChainAccountKit({ account, address, diff --git a/packages/orchestration/src/exos/chainAccountKit.js b/packages/orchestration/src/exos/chainAccountKit.js index 187b661ea8e..1189055a5cb 100644 --- a/packages/orchestration/src/exos/chainAccountKit.js +++ b/packages/orchestration/src/exos/chainAccountKit.js @@ -131,7 +131,7 @@ export const prepareChainAccountKit = zone => }, /** Close the remote account */ async close() { - /// XXX what should the behavior be here? and `onClose`? + // FIXME what should the behavior be here? and `onClose`? // - retrieve assets? // - revoke the port? const { connection } = this.state; @@ -169,7 +169,7 @@ export const prepareChainAccountKit = zone => }, async onClose(_connection, reason) { trace(`ICA Channel closed. Reason: ${reason}`); - // XXX handle connection closing + // FIXME handle connection closing // XXX is there a scenario where a connection will unexpectedly close? _I think yes_ }, async onReceive(connection, bytes) { diff --git a/packages/orchestration/src/service.js b/packages/orchestration/src/service.js index 3c203914296..2681a787b89 100644 --- a/packages/orchestration/src/service.js +++ b/packages/orchestration/src/service.js @@ -133,7 +133,7 @@ const prepareOrchestrationKit = ( remoteConnAddr, chainAccountKit.connectionHandler, ); - // XXX if we fail, should we close the port (if it was created in this flow)? + // FIXME if we fail, should we close the port (if it was created in this flow)? return chainAccountKit.account; }, /** diff --git a/packages/orchestration/src/utils/chainHub.js b/packages/orchestration/src/utils/chainHub.js index d1df713d5c1..11323e4c090 100644 --- a/packages/orchestration/src/utils/chainHub.js +++ b/packages/orchestration/src/utils/chainHub.js @@ -163,7 +163,7 @@ export const registerChain = async ( .then(() => log(`registered agoricNames chain.${name}`)), ]; - // XXX updates redundantly, twice per edge + // FIXME updates redundantly, twice per edge for await (const [counterChainId, connInfo] of Object.entries(connections)) { const key = connectionKey(chainInfo.chainId, counterChainId); promises.push( diff --git a/packages/orchestration/src/utils/orc.js b/packages/orchestration/src/utils/orc.js index e4dd7895216..80333accc44 100644 --- a/packages/orchestration/src/utils/orc.js +++ b/packages/orchestration/src/utils/orc.js @@ -8,7 +8,7 @@ export const orcUtils = { * @returns {TransferMsg} */ makeTransferMsg: _args => { - // XXX mocked, so typescript is happy + // FIXME mocked, so typescript is happy return { toAccount: { chainId: 'osmosis-test', @@ -26,7 +26,7 @@ export const orcUtils = { * @returns {TransferMsg} */ makeOsmosisSwap(_args) { - // XXX mocked, so typescript is happy + // FIXME mocked, so typescript is happy return { toAccount: { chainId: 'osmosis-test', diff --git a/packages/orchestration/src/utils/start-helper.js b/packages/orchestration/src/utils/start-helper.js index 6fcf3fb8d36..02f34d81e2b 100644 --- a/packages/orchestration/src/utils/start-helper.js +++ b/packages/orchestration/src/utils/start-helper.js @@ -62,7 +62,7 @@ export const provideOrchestration = ( }); const makeCosmosOrchestrationAccount = prepareCosmosOrchestrationAccount( - // XXX what zone? + // FIXME what zone? zone, makeRecorderKit, zcf, From 29649ad508e7a67ab8c31d59b79bc7f8fced3b1f Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Wed, 19 Jun 2024 07:19:54 -0700 Subject: [PATCH 03/10] refactor: kebab case exo filenames --- packages/orchestration/src/examples/stakeIca.contract.js | 2 +- .../src/exos/{chainAccountKit.js => chain-account-kit.js} | 0 ...rchestrationAccount.js => cosmos-orchestration-account.js} | 0 .../src/exos/{icqConnectionKit.js => icq-connection-kit.js} | 0 packages/orchestration/src/exos/remote-chain-facade.js | 2 +- packages/orchestration/src/service.js | 4 ++-- packages/orchestration/src/types.ts | 4 ++-- packages/orchestration/src/utils/start-helper.js | 2 +- packages/orchestration/test/staking-ops.test.ts | 2 +- packages/orchestration/test/types.test-d.ts | 2 +- 10 files changed, 9 insertions(+), 9 deletions(-) rename packages/orchestration/src/exos/{chainAccountKit.js => chain-account-kit.js} (100%) rename packages/orchestration/src/exos/{cosmosOrchestrationAccount.js => cosmos-orchestration-account.js} (100%) rename packages/orchestration/src/exos/{icqConnectionKit.js => icq-connection-kit.js} (100%) diff --git a/packages/orchestration/src/examples/stakeIca.contract.js b/packages/orchestration/src/examples/stakeIca.contract.js index 40fc24c08e1..e700f275468 100644 --- a/packages/orchestration/src/examples/stakeIca.contract.js +++ b/packages/orchestration/src/examples/stakeIca.contract.js @@ -10,7 +10,7 @@ import { import { InvitationShape } from '@agoric/zoe/src/typeGuards.js'; import { makeDurableZone } from '@agoric/zone/durable.js'; import { M } from '@endo/patterns'; -import { prepareCosmosOrchestrationAccount } from '../exos/cosmosOrchestrationAccount.js'; +import { prepareCosmosOrchestrationAccount } from '../exos/cosmos-orchestration-account.js'; const trace = makeTracer('StakeAtom'); /** diff --git a/packages/orchestration/src/exos/chainAccountKit.js b/packages/orchestration/src/exos/chain-account-kit.js similarity index 100% rename from packages/orchestration/src/exos/chainAccountKit.js rename to packages/orchestration/src/exos/chain-account-kit.js diff --git a/packages/orchestration/src/exos/cosmosOrchestrationAccount.js b/packages/orchestration/src/exos/cosmos-orchestration-account.js similarity index 100% rename from packages/orchestration/src/exos/cosmosOrchestrationAccount.js rename to packages/orchestration/src/exos/cosmos-orchestration-account.js diff --git a/packages/orchestration/src/exos/icqConnectionKit.js b/packages/orchestration/src/exos/icq-connection-kit.js similarity index 100% rename from packages/orchestration/src/exos/icqConnectionKit.js rename to packages/orchestration/src/exos/icq-connection-kit.js diff --git a/packages/orchestration/src/exos/remote-chain-facade.js b/packages/orchestration/src/exos/remote-chain-facade.js index c8d50d5c50c..15c70101274 100644 --- a/packages/orchestration/src/exos/remote-chain-facade.js +++ b/packages/orchestration/src/exos/remote-chain-facade.js @@ -10,7 +10,7 @@ import { ChainInfoShape } from './orchestrator.js'; * @import {TimerService} from '@agoric/time'; * @import {Remote} from '@agoric/internal'; * @import {OrchestrationService} from '../service.js'; - * @import {prepareCosmosOrchestrationAccount} from './cosmosOrchestrationAccount.js'; + * @import {prepareCosmosOrchestrationAccount} from './cosmos-orchestration-account.js'; * @import {ChainInfo, CosmosChainInfo, IBCConnectionInfo, OrchestrationAccount} from '../types.js'; */ diff --git a/packages/orchestration/src/service.js b/packages/orchestration/src/service.js index 2681a787b89..39fc4fa9c41 100644 --- a/packages/orchestration/src/service.js +++ b/packages/orchestration/src/service.js @@ -3,8 +3,8 @@ import { V as E } from '@agoric/vow/vat.js'; import { M } from '@endo/patterns'; import { Shape as NetworkShape } from '@agoric/network'; -import { prepareChainAccountKit } from './exos/chainAccountKit.js'; -import { prepareICQConnectionKit } from './exos/icqConnectionKit.js'; +import { prepareChainAccountKit } from './exos/chain-account-kit.js'; +import { prepareICQConnectionKit } from './exos/icq-connection-kit.js'; import { makeICAChannelAddress, makeICQChannelAddress, diff --git a/packages/orchestration/src/types.ts b/packages/orchestration/src/types.ts index 151bf3bb83b..42c0f81af80 100644 --- a/packages/orchestration/src/types.ts +++ b/packages/orchestration/src/types.ts @@ -3,8 +3,8 @@ export type * from './chain-info.js'; export type * from './cosmos-api.js'; export type * from './ethereum-api.js'; -export type * from './exos/chainAccountKit.js'; -export type * from './exos/icqConnectionKit.js'; +export type * from './exos/chain-account-kit.js'; +export type * from './exos/icq-connection-kit.js'; export type * from './orchestration-api.js'; export type * from './service.js'; export type * from './vat-orchestration.js'; diff --git a/packages/orchestration/src/utils/start-helper.js b/packages/orchestration/src/utils/start-helper.js index 02f34d81e2b..637cc80ac1f 100644 --- a/packages/orchestration/src/utils/start-helper.js +++ b/packages/orchestration/src/utils/start-helper.js @@ -6,7 +6,7 @@ import { prepareLocalChainAccountKit } from '../exos/local-chain-account-kit.js' import { makeOrchestrationFacade } from '../facade.js'; import { makeChainHub } from './chainHub.js'; import { prepareRemoteChainFacade } from '../exos/remote-chain-facade.js'; -import { prepareCosmosOrchestrationAccount } from '../exos/cosmosOrchestrationAccount.js'; +import { prepareCosmosOrchestrationAccount } from '../exos/cosmos-orchestration-account.js'; /** * @import {PromiseKit} from '@endo/promise-kit' diff --git a/packages/orchestration/test/staking-ops.test.ts b/packages/orchestration/test/staking-ops.test.ts index f6eb1bd8e9a..8bbe71c6388 100644 --- a/packages/orchestration/test/staking-ops.test.ts +++ b/packages/orchestration/test/staking-ops.test.ts @@ -23,7 +23,7 @@ import { prepareRecorderKitMakers } from '@agoric/zoe/src/contractSupport/record import { prepareCosmosOrchestrationAccountKit, trivialDelegateResponse, -} from '../src/exos/cosmosOrchestrationAccount.js'; +} from '../src/exos/cosmos-orchestration-account.js'; import { encodeTxResponse } from '../src/utils/cosmos.js'; import type { IcaAccount, ChainAddress, ICQConnection } from '../src/types.js'; diff --git a/packages/orchestration/test/types.test-d.ts b/packages/orchestration/test/types.test-d.ts index 37095f7538d..8ae786324e8 100644 --- a/packages/orchestration/test/types.test-d.ts +++ b/packages/orchestration/test/types.test-d.ts @@ -11,7 +11,7 @@ import type { StakingAccountActions, } from '../src/types.js'; import type { LocalChainAccountKit } from '../src/exos/local-chain-account-kit.js'; -import { prepareCosmosOrchestrationAccount } from '../src/exos/cosmosOrchestrationAccount.js'; +import { prepareCosmosOrchestrationAccount } from '../src/exos/cosmos-orchestration-account.js'; const anyVal = null as any; From 783f520960e89b37d6a971348ffac5a2f720472a Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Wed, 19 Jun 2024 07:51:04 -0700 Subject: [PATCH 04/10] refactor: ChainAddress in localchain account --- .../src/examples/stakeBld.contract.js | 6 ++++- .../src/exos/local-chain-account-kit.js | 9 ++++--- packages/orchestration/src/facade.js | 13 +++++----- .../test/examples/stake-bld.contract.test.ts | 1 - .../test/exos/local-chain-account-kit.test.ts | 24 ++++++++++++------- 5 files changed, 31 insertions(+), 22 deletions(-) diff --git a/packages/orchestration/src/examples/stakeBld.contract.js b/packages/orchestration/src/examples/stakeBld.contract.js index c3adbd178fb..ce9c189fad4 100644 --- a/packages/orchestration/src/examples/stakeBld.contract.js +++ b/packages/orchestration/src/examples/stakeBld.contract.js @@ -61,7 +61,11 @@ export const start = async (zcf, privateArgs, baggage) => { // FIXME 'address' is implied by 'account'; use an async maker that get the value itself return makeLocalChainAccountKit({ account, - address, + address: harden({ + address, + addressEncoding: 'bech32', + chainId: 'local', + }), storageNode: privateArgs.storageNode, }); } diff --git a/packages/orchestration/src/exos/local-chain-account-kit.js b/packages/orchestration/src/exos/local-chain-account-kit.js index 14f2935dd1c..28eb3ef25fe 100644 --- a/packages/orchestration/src/exos/local-chain-account-kit.js +++ b/packages/orchestration/src/exos/local-chain-account-kit.js @@ -38,7 +38,7 @@ const { Fail } = assert; * @typedef {{ * topicKit: RecorderKit; * account: LocalChainAccount; - * address: ChainAddress['address']; + * address: ChainAddress; * }} State */ @@ -92,7 +92,7 @@ export const prepareLocalChainAccountKit = ( /** * @param {object} initState * @param {LocalChainAccount} initState.account - * @param {ChainAddress['address']} initState.address + * @param {ChainAddress} initState.address * @param {StorageNode} initState.storageNode * @returns {State} */ @@ -101,7 +101,6 @@ export const prepareLocalChainAccountKit = ( // @ts-expect-error XXX Patterns const topicKit = makeRecorderKit(storageNode, PUBLIC_TOPICS.account[1]); - // #9162 use ChainAddress object instead of `address` string return { account, address, topicKit }; }, { @@ -220,7 +219,7 @@ export const prepareLocalChainAccountKit = ( // @ts-expect-error subtype return V(this.state.account).executeTx(messages); }, - /** @returns {ChainAddress['address']} */ + /** @returns {ChainAddress} */ getAddress() { return NonNullish(this.state.address, 'Chain address not available.'); }, @@ -261,7 +260,7 @@ export const prepareLocalChainAccountKit = ( amount: String(amount.value), denom: amount.denom, }, - sender: this.state.address, + sender: this.state.address.address, receiver: destination.address, timeoutHeight: opts?.timeoutHeight ?? { revisionHeight: 0n, diff --git a/packages/orchestration/src/facade.js b/packages/orchestration/src/facade.js index 8fe45036f7c..75aed469173 100644 --- a/packages/orchestration/src/facade.js +++ b/packages/orchestration/src/facade.js @@ -44,7 +44,11 @@ export const makeLocalChainFacade = ( const [lca, address] = await Promise.all([lcaP, E(lcaP).getAddress()]); const { holder: account } = makeLocalChainAccountKit({ account: lca, - address, + address: harden({ + address, + chainId: localInfo.chainId, + addressEncoding: 'bech32', + }), // @ts-expect-error TODO: Remote storageNode: null, }); @@ -56,12 +60,7 @@ export const makeLocalChainFacade = ( await E(account).deposit(payment); }, getAddress() { - const addressStr = account.getAddress(); - return { - address: addressStr, - chainId: localInfo.chainId, - addressEncoding: 'bech32', - }; + return account.getAddress(); }, async getBalance(denomArg) { // FIXME look up real values diff --git a/packages/orchestration/test/examples/stake-bld.contract.test.ts b/packages/orchestration/test/examples/stake-bld.contract.test.ts index 489afa865a3..0a36b59cdf7 100644 --- a/packages/orchestration/test/examples/stake-bld.contract.test.ts +++ b/packages/orchestration/test/examples/stake-bld.contract.test.ts @@ -51,7 +51,6 @@ test('makeAccount, deposit, withdraw', async t => { t.log('make a LocalChainAccount'); const account = await E(publicFacet).makeAccount(); t.truthy(account, 'account is returned'); - t.regex(await E(account).getAddress(), /agoric1/); t.log('deposit 100 bld to account'); const depositResp = await V(account).deposit( diff --git a/packages/orchestration/test/exos/local-chain-account-kit.test.ts b/packages/orchestration/test/exos/local-chain-account-kit.test.ts index 88547d4f22f..69325d6ce87 100644 --- a/packages/orchestration/test/exos/local-chain-account-kit.test.ts +++ b/packages/orchestration/test/exos/local-chain-account-kit.test.ts @@ -40,12 +40,14 @@ test('deposit, withdraw', async t => { t.log('make a LocalChainAccountKit'); const { holder: account } = makeLocalChainAccountKit({ account: lca, - address, + address: harden({ + address, + chainId: 'agoric-n', + addressEncoding: 'bech32', + }), storageNode: storage.rootNode.makeChildNode('lcaKit'), }); - t.regex(await E(account).getAddress(), /agoric1/); - const oneHundredStakePmt = await utils.pourPayment(stake.units(100)); t.log('deposit 100 bld to account'); @@ -104,12 +106,14 @@ test('delegate, undelegate', async t => { t.log('make a LocalChainAccountKit'); const { holder: account } = makeLocalChainAccountKit({ account: lca, - address, + address: harden({ + address, + chainId: 'agoric-n', + addressEncoding: 'bech32', + }), storageNode: storage.rootNode.makeChildNode('lcaKit'), }); - t.regex(await E(account).getAddress(), /agoric1/); - await E(account).deposit(await utils.pourPayment(bld.units(100))); const validatorAddress = 'agoric1validator1'; @@ -121,6 +125,7 @@ test('delegate, undelegate', async t => { await E(account).delegate(validatorAddress, bld.units(999)); // TODO get the timer to fire so that this promise resolves void E(account).undelegate(validatorAddress, bld.units(999)); + t.pass(); }); test('transfer', async t => { @@ -151,12 +156,15 @@ test('transfer', async t => { t.log('make a LocalChainAccountKit'); const { holder: account } = makeLocalChainAccountKit({ account: lca, - address, + address: harden({ + address, + chainId: 'agoric-n', + addressEncoding: 'bech32', + }), storageNode: storage.rootNode.makeChildNode('lcaKit'), }); t.truthy(account, 'account is returned'); - t.regex(await E(account).getAddress(), /agoric1/); const oneHundredStakePmt = await utils.pourPayment(stake.units(100)); From 5ce13fdfd238914b268ec60e91d5a449f5ac8e5d Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Wed, 19 Jun 2024 08:10:36 -0700 Subject: [PATCH 05/10] feat: OrchestrationAccountI for LCA holder --- .../src/examples/sendAnywhere.contract.js | 3 +- .../src/examples/swapExample.contract.js | 7 ++- .../src/exos/local-chain-account-kit.js | 53 +++++++++++++------ packages/orchestration/src/facade.js | 37 +------------ .../src/utils/orchestrationAccount.js | 7 ++- .../test/examples/stake-bld.contract.test.ts | 5 +- .../test/exos/local-chain-account-kit.test.ts | 8 +-- 7 files changed, 55 insertions(+), 65 deletions(-) diff --git a/packages/orchestration/src/examples/sendAnywhere.contract.js b/packages/orchestration/src/examples/sendAnywhere.contract.js index 4b6c37982f5..5319e1fe0f9 100644 --- a/packages/orchestration/src/examples/sendAnywhere.contract.js +++ b/packages/orchestration/src/examples/sendAnywhere.contract.js @@ -52,6 +52,7 @@ export const start = async (zcf, privateArgs, baggage) => { privateArgs.marshaller, ); + /** @type {import('../orchestration-api.js').OrchestrationAccount} */ let contractAccount; const findBrandInVBank = async brand => { @@ -88,7 +89,7 @@ export const start = async (zcf, privateArgs, baggage) => { const info = await chain.getChainInfo(); const { chainId } = info; const { [kw]: pmtP } = await withdrawFromSeat(zcf, seat, give); - await E.when(pmtP, pmt => contractAccount.deposit(pmt, amt)); + await E.when(pmtP, pmt => contractAccount.deposit(pmt)); await contractAccount.transfer( { denom, value: amt.value }, { diff --git a/packages/orchestration/src/examples/swapExample.contract.js b/packages/orchestration/src/examples/swapExample.contract.js index f50a70d1d87..cba2326800e 100644 --- a/packages/orchestration/src/examples/swapExample.contract.js +++ b/packages/orchestration/src/examples/swapExample.contract.js @@ -103,7 +103,12 @@ export const start = async (zcf, privateArgs, baggage) => { // deposit funds from user seat to LocalChainAccount const payments = await withdrawFromSeat(zcf, seat, give); - await deeplyFulfilled(objectMap(payments, localAccount.deposit)); + await deeplyFulfilled( + objectMap(payments, payment => + // @ts-expect-error payment is ERef which happens to work but isn't officially supported + localAccount.deposit(payment), + ), + ); seat.exit(); // build swap instructions with orcUtils library diff --git a/packages/orchestration/src/exos/local-chain-account-kit.js b/packages/orchestration/src/exos/local-chain-account-kit.js index 28eb3ef25fe..133cf7c5b4d 100644 --- a/packages/orchestration/src/exos/local-chain-account-kit.js +++ b/packages/orchestration/src/exos/local-chain-account-kit.js @@ -1,24 +1,19 @@ /** @file Use-object for the owner of a localchain account */ -import { NonNullish } from '@agoric/assert'; import { typedJson } from '@agoric/cosmic-proto/vatsafe'; import { AmountShape, PaymentShape } from '@agoric/ertp'; import { makeTracer } from '@agoric/internal'; import { M } from '@agoric/vat-data'; +import { V } from '@agoric/vow/vat.js'; import { TopicsRecordShape } from '@agoric/zoe/src/contractSupport/index.js'; import { InvitationShape } from '@agoric/zoe/src/typeGuards.js'; -import { V } from '@agoric/vow/vat.js'; import { E } from '@endo/far'; -import { - AmountArgShape, - ChainAddressShape, - IBCTransferOptionsShape, -} from '../typeGuards.js'; import { maxClockSkew } from '../utils/cosmos.js'; +import { orchestrationAccountMethods } from '../utils/orchestrationAccount.js'; import { dateInSeconds, makeTimestampHelper } from '../utils/time.js'; /** * @import {LocalChainAccount} from '@agoric/vats/src/localchain.js'; - * @import {AmountArg, ChainAddress, DenomAmount, IBCMsgTransferOptions, CosmosChainInfo} from '@agoric/orchestration'; + * @import {AmountArg, ChainAddress, DenomAmount, IBCMsgTransferOptions, OrchestrationAccount, OrchestrationAccountI} from '@agoric/orchestration'; * @import {RecorderKit, MakeRecorderKit} from '@agoric/zoe/src/contractSupport/recorder.js'. * @import {Zone} from '@agoric/zone'; * @import {Remote} from '@agoric/internal'; @@ -43,15 +38,11 @@ const { Fail } = assert; */ const HolderI = M.interface('holder', { + ...orchestrationAccountMethods, getPublicTopics: M.call().returns(TopicsRecordShape), delegate: M.call(M.string(), AmountShape).returns(M.promise()), undelegate: M.call(M.string(), AmountShape).returns(M.promise()), - deposit: M.callWhen(PaymentShape).optional(AmountShape).returns(AmountShape), withdraw: M.callWhen(AmountShape).returns(PaymentShape), - transfer: M.call(AmountArgShape, ChainAddressShape) - .optional(IBCTransferOptionsShape) - .returns(M.promise()), - getAddress: M.call().returns(M.string()), executeTx: M.callWhen(M.arrayOf(M.record())).returns(M.arrayOf(M.record())), }); @@ -75,6 +66,7 @@ export const prepareLocalChainAccountKit = ( chainHub, ) => { const timestampHelper = makeTimestampHelper(timerService); + // TODO: rename to makeLocalOrchestrationAccount or the like to distinguish from lca /** Make an object wrapping an LCA with Zoe interfaces. */ const makeLocalChainAccountKit = zone.exoClassKit( @@ -137,6 +129,24 @@ export const prepareLocalChainAccountKit = ( }, }, holder: { + /** @type {OrchestrationAccount['getBalance']} */ + async getBalance(denomArg) { + // FIXME look up real values + // UNTIL https://github.com/Agoric/agoric-sdk/issues/9211 + const [brand, denom] = + typeof denomArg === 'string' + ? [/** @type {any} */ (null), denomArg] + : [denomArg, 'FIXME']; + + const natAmount = await V.when( + E(this.state.account).getBalance(brand), + ); + return harden({ denom, value: natAmount.value }); + }, + getBalances() { + throw new Error('not yet implemented'); + }, + getPublicTopics() { const { topicKit } = this.state; return harden({ @@ -206,9 +216,9 @@ export const prepareLocalChainAccountKit = ( * updater will get a special notification that the account is being * transferred. */ - /** @type {LocalChainAccount['deposit']} */ - async deposit(payment, optAmountShape) { - return V(this.state.account).deposit(payment, optAmountShape); + /** @type {OrchestrationAccount['deposit']} */ + async deposit(payment) { + await V(this.state.account).deposit(payment); }, /** @type {LocalChainAccount['withdraw']} */ async withdraw(amount) { @@ -221,7 +231,11 @@ export const prepareLocalChainAccountKit = ( }, /** @returns {ChainAddress} */ getAddress() { - return NonNullish(this.state.address, 'Chain address not available.'); + return this.state.address; + }, + async send(toAccount, amount) { + // FIXME implement + console.log('send got', toAccount, amount); }, /** * @param {AmountArg} amount an ERTP {@link Amount} or a @@ -272,6 +286,11 @@ export const prepareLocalChainAccountKit = ( ]); trace('MsgTransfer result', result); }, + /** @type {OrchestrationAccount['transferSteps']} */ + transferSteps(amount, msg) { + console.log('transferSteps got', amount, msg); + return Promise.resolve(); + }, }, }, ); diff --git a/packages/orchestration/src/facade.js b/packages/orchestration/src/facade.js index 75aed469173..af90b461716 100644 --- a/packages/orchestration/src/facade.js +++ b/packages/orchestration/src/facade.js @@ -53,42 +53,7 @@ export const makeLocalChainFacade = ( storageNode: null, }); - // FIXME turn this into an Exo LocalChainOrchestrationAccount or make that a facet of makeLocalChainAccountKit - return { - async deposit(payment) { - console.log('deposit got', payment); - await E(account).deposit(payment); - }, - getAddress() { - return account.getAddress(); - }, - async getBalance(denomArg) { - // FIXME look up real values - // UNTIL https://github.com/Agoric/agoric-sdk/issues/9211 - const [brand, denom] = - typeof denomArg === 'string' - ? [/** @type {any} */ (null), denomArg] - : [denomArg, 'FIXME']; - - const natAmount = await E(lca).getBalance(brand); - return harden({ denom, value: natAmount.value }); - }, - getBalances() { - throw new Error('not yet implemented'); - }, - async send(toAccount, amount) { - // FIXME implement - console.log('send got', toAccount, amount); - }, - async transfer(amount, destination, opts) { - console.log('transfer got', amount, destination, opts); - return account.transfer(amount, destination, opts); - }, - transferSteps(amount, msg) { - console.log('transferSteps got', amount, msg); - return Promise.resolve(); - }, - }; + return account; }, }); }; diff --git a/packages/orchestration/src/utils/orchestrationAccount.js b/packages/orchestration/src/utils/orchestrationAccount.js index b5b325980c1..b4824919706 100644 --- a/packages/orchestration/src/utils/orchestrationAccount.js +++ b/packages/orchestration/src/utils/orchestrationAccount.js @@ -4,16 +4,15 @@ import { AmountArgShape, ChainAddressShape, CoinShape } from '../typeGuards.js'; /** @import {OrchestrationAccountI} from '../orchestration-api.js'; */ -// TODO complete this interface /** @see {OrchestrationAccountI} */ export const orchestrationAccountMethods = { getAddress: M.call().returns(ChainAddressShape), getBalance: M.callWhen(M.any()).returns(CoinShape), getBalances: M.callWhen().returns(M.arrayOf(CoinShape)), send: M.callWhen(ChainAddressShape, AmountArgShape).returns(M.undefined()), - transfer: M.callWhen(AmountArgShape, ChainAddressShape).returns( - M.undefined(), - ), + transfer: M.callWhen(AmountArgShape, ChainAddressShape) + .optional(M.record()) + .returns(M.undefined()), transferSteps: M.callWhen(AmountArgShape, M.any()).returns(M.undefined()), deposit: M.callWhen(PaymentShape).returns(M.undefined()), }; diff --git a/packages/orchestration/test/examples/stake-bld.contract.test.ts b/packages/orchestration/test/examples/stake-bld.contract.test.ts index 0a36b59cdf7..db6ef562ab4 100644 --- a/packages/orchestration/test/examples/stake-bld.contract.test.ts +++ b/packages/orchestration/test/examples/stake-bld.contract.test.ts @@ -56,9 +56,8 @@ test('makeAccount, deposit, withdraw', async t => { const depositResp = await V(account).deposit( await utils.pourPayment(bld.units(100)), ); - t.true(AmountMath.isEqual(depositResp, bld.units(100)), 'deposit'); - - // TODO validate balance, .getBalance() + // FIXME #9211 + // t.deepEqual(await E(account).getBalance('ubld'), bld.units(100)); t.log('withdraw bld from account'); const withdrawResp = await V(account).withdraw(bld.units(100)); diff --git a/packages/orchestration/test/exos/local-chain-account-kit.test.ts b/packages/orchestration/test/exos/local-chain-account-kit.test.ts index 69325d6ce87..8090980279a 100644 --- a/packages/orchestration/test/exos/local-chain-account-kit.test.ts +++ b/packages/orchestration/test/exos/local-chain-account-kit.test.ts @@ -52,7 +52,8 @@ test('deposit, withdraw', async t => { t.log('deposit 100 bld to account'); const depositResp = await E(account).deposit(oneHundredStakePmt); - t.true(AmountMath.isEqual(depositResp, stake.units(100)), 'deposit'); + // FIXME #9211 + // t.deepEqual(await E(account).getBalance('ubld'), stake.units(100)); const withdrawal1 = await E(account).withdraw(stake.units(50)); t.true( @@ -169,8 +170,9 @@ test('transfer', async t => { const oneHundredStakePmt = await utils.pourPayment(stake.units(100)); t.log('deposit 100 bld to account'); - const depositResp = await E(account).deposit(oneHundredStakePmt); - t.true(AmountMath.isEqual(depositResp, stake.units(100)), 'deposit'); + await E(account).deposit(oneHundredStakePmt); + // FIXME #9211 + // t.deepEqual(await E(account).getBalance('ubld'), stake.units(100)); const destination: ChainAddress = { chainId: 'cosmoshub-4', From 1ca9a008bca9b34af8da9150027802517fa066d7 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Wed, 19 Jun 2024 08:22:04 -0700 Subject: [PATCH 06/10] refactor: name LocalOrchestrationAccount --- .../src/examples/stakeBld.contract.js | 4 ++-- ...ount-kit.js => local-orchestration-account.js} | 15 +++++++-------- packages/orchestration/src/exos/orchestrator.js | 4 ++-- packages/orchestration/src/facade.js | 4 ++-- packages/orchestration/src/utils/start-helper.js | 4 ++-- ...ts => local-orchestration-account-kit.test.ts} | 8 ++++---- packages/orchestration/test/types.test-d.ts | 4 ++-- 7 files changed, 21 insertions(+), 22 deletions(-) rename packages/orchestration/src/exos/{local-chain-account-kit.js => local-orchestration-account.js} (96%) rename packages/orchestration/test/exos/{local-chain-account-kit.test.ts => local-orchestration-account-kit.test.ts} (95%) diff --git a/packages/orchestration/src/examples/stakeBld.contract.js b/packages/orchestration/src/examples/stakeBld.contract.js index ce9c189fad4..2bb8bb8215a 100644 --- a/packages/orchestration/src/examples/stakeBld.contract.js +++ b/packages/orchestration/src/examples/stakeBld.contract.js @@ -10,7 +10,7 @@ import { V } from '@agoric/vow/vat.js'; import { E } from '@endo/far'; import { deeplyFulfilled } from '@endo/marshal'; import { M } from '@endo/patterns'; -import { prepareLocalChainAccountKit } from '../exos/local-chain-account-kit.js'; +import { prepareLocalOrchestrationAccountKit } from '../exos/local-orchestration-account.js'; import { makeChainHub } from '../utils/chainHub.js'; /** @@ -41,7 +41,7 @@ export const start = async (zcf, privateArgs, baggage) => { privateArgs.marshaller, ); - const makeLocalChainAccountKit = prepareLocalChainAccountKit( + const makeLocalChainAccountKit = prepareLocalOrchestrationAccountKit( zone, makeRecorderKit, zcf, diff --git a/packages/orchestration/src/exos/local-chain-account-kit.js b/packages/orchestration/src/exos/local-orchestration-account.js similarity index 96% rename from packages/orchestration/src/exos/local-chain-account-kit.js rename to packages/orchestration/src/exos/local-orchestration-account.js index 133cf7c5b4d..1f015a580f7 100644 --- a/packages/orchestration/src/exos/local-chain-account-kit.js +++ b/packages/orchestration/src/exos/local-orchestration-account.js @@ -21,7 +21,7 @@ import { dateInSeconds, makeTimestampHelper } from '../utils/time.js'; * @import {ChainHub} from '../utils/chainHub.js'; */ -const trace = makeTracer('LCAH'); +const trace = makeTracer('LOA'); const { Fail } = assert; /** @@ -58,7 +58,7 @@ const PUBLIC_TOPICS = { * @param {Remote} timerService * @param {ChainHub} chainHub */ -export const prepareLocalChainAccountKit = ( +export const prepareLocalOrchestrationAccountKit = ( zone, makeRecorderKit, zcf, @@ -67,10 +67,9 @@ export const prepareLocalChainAccountKit = ( ) => { const timestampHelper = makeTimestampHelper(timerService); - // TODO: rename to makeLocalOrchestrationAccount or the like to distinguish from lca /** Make an object wrapping an LCA with Zoe interfaces. */ - const makeLocalChainAccountKit = zone.exoClassKit( - 'LCA Kit', + const makeLocalOrchestrationAccountKit = zone.exoClassKit( + 'Local Orchestration Account Kit', { holder: HolderI, invitationMakers: M.interface('invitationMakers', { @@ -294,7 +293,7 @@ export const prepareLocalChainAccountKit = ( }, }, ); - return makeLocalChainAccountKit; + return makeLocalOrchestrationAccountKit; }; -/** @typedef {ReturnType} MakeLocalChainAccountKit */ -/** @typedef {ReturnType} LocalChainAccountKit */ +/** @typedef {ReturnType} MakeLocalOrchestrationAccountKit */ +/** @typedef {ReturnType} LocalOrchestrationAccountKit */ diff --git a/packages/orchestration/src/exos/orchestrator.js b/packages/orchestration/src/exos/orchestrator.js index 294a3bcffe7..8c007b7e4dc 100644 --- a/packages/orchestration/src/exos/orchestrator.js +++ b/packages/orchestration/src/exos/orchestrator.js @@ -21,7 +21,7 @@ import { makeLocalChainFacade } from '../facade.js'; * @import {RecorderKit, MakeRecorderKit} from '@agoric/zoe/src/contractSupport/recorder.js'. * @import {Remote} from '@agoric/internal'; * @import {OrchestrationService} from '../service.js'; - * @import {MakeLocalChainAccountKit} from './local-chain-account-kit.js'; + * @import {MakeLocalOrchestrationAccountKit} from './local-orchestration-account.js'; * @import {Chain, ChainInfo, CosmosChainInfo, IBCConnectionInfo, OrchestrationAccount, Orchestrator} from '../types.js'; */ @@ -50,7 +50,7 @@ export const OrchestratorI = M.interface('Orchestrator', { * asyncFlowTools: AsyncFlowTools; * chainHub: ChainHub; * localchain: Remote; - * makeLocalChainAccountKit: MakeLocalChainAccountKit; + * makeLocalChainAccountKit: MakeLocalOrchestrationAccountKit; * makeRecorderKit: MakeRecorderKit; * makeRemoteChainFacade: any; * orchestrationService: Remote; diff --git a/packages/orchestration/src/facade.js b/packages/orchestration/src/facade.js index af90b461716..08f42bbd2bd 100644 --- a/packages/orchestration/src/facade.js +++ b/packages/orchestration/src/facade.js @@ -23,7 +23,7 @@ import { prepareOrchestrator } from './exos/orchestrator.js'; /** * @param {Remote} localchain * @param {ReturnType< - * typeof import('./exos/local-chain-account-kit.js').prepareLocalChainAccountKit + * typeof import('./exos/local-orchestration-account.js').prepareLocalOrchestrationAccountKit * >} makeLocalChainAccountKit * @param {ChainInfo} localInfo * @returns {Chain} @@ -68,7 +68,7 @@ export const makeLocalChainFacade = ( * localchain: Remote; * chainHub: import('./utils/chainHub.js').ChainHub; * makeLocalChainAccountKit: ReturnType< - * typeof import('./exos/local-chain-account-kit.js').prepareLocalChainAccountKit + * typeof import('./exos/local-orchestration-account.js').prepareLocalOrchestrationAccountKit * >; * makeRecorderKit: MakeRecorderKit; * makeCosmosOrchestrationAccount: any; diff --git a/packages/orchestration/src/utils/start-helper.js b/packages/orchestration/src/utils/start-helper.js index 637cc80ac1f..b9fbbf7cbf6 100644 --- a/packages/orchestration/src/utils/start-helper.js +++ b/packages/orchestration/src/utils/start-helper.js @@ -2,7 +2,7 @@ import { prepareAsyncFlowTools } from '@agoric/async-flow'; import { prepareVowTools } from '@agoric/vow'; import { prepareRecorderKitMakers } from '@agoric/zoe/src/contractSupport/recorder.js'; import { makeDurableZone } from '@agoric/zone/durable.js'; -import { prepareLocalChainAccountKit } from '../exos/local-chain-account-kit.js'; +import { prepareLocalOrchestrationAccountKit } from '../exos/local-orchestration-account.js'; import { makeOrchestrationFacade } from '../facade.js'; import { makeChainHub } from './chainHub.js'; import { prepareRemoteChainFacade } from '../exos/remote-chain-facade.js'; @@ -48,7 +48,7 @@ export const provideOrchestration = ( const chainHub = makeChainHub(remotePowers.agoricNames); const { makeRecorderKit } = prepareRecorderKitMakers(baggage, marshaller); - const makeLocalChainAccountKit = prepareLocalChainAccountKit( + const makeLocalChainAccountKit = prepareLocalOrchestrationAccountKit( zone, makeRecorderKit, zcf, diff --git a/packages/orchestration/test/exos/local-chain-account-kit.test.ts b/packages/orchestration/test/exos/local-orchestration-account-kit.test.ts similarity index 95% rename from packages/orchestration/test/exos/local-chain-account-kit.test.ts rename to packages/orchestration/test/exos/local-orchestration-account-kit.test.ts index 8090980279a..37b30d2aa55 100644 --- a/packages/orchestration/test/exos/local-chain-account-kit.test.ts +++ b/packages/orchestration/test/exos/local-orchestration-account-kit.test.ts @@ -5,7 +5,7 @@ import { prepareRecorderKitMakers } from '@agoric/zoe/src/contractSupport/record import { V as E } from '@agoric/vow/vat.js'; import { Far } from '@endo/far'; import { commonSetup } from '../supports.js'; -import { prepareLocalChainAccountKit } from '../../src/exos/local-chain-account-kit.js'; +import { prepareLocalOrchestrationAccountKit } from '../../src/exos/local-orchestration-account.js'; import { ChainAddress } from '../../src/orchestration-api.js'; import { NANOSECONDS_PER_SECOND } from '../../src/utils/time.js'; import { makeChainHub } from '../../src/utils/chainHub.js'; @@ -24,7 +24,7 @@ test('deposit, withdraw', async t => { rootZone.mapStore('recorder'), marshaller, ); - const makeLocalChainAccountKit = prepareLocalChainAccountKit( + const makeLocalChainAccountKit = prepareLocalOrchestrationAccountKit( rootZone, makeRecorderKit, // @ts-expect-error mocked zcf. use `stake-bld.contract.test.ts` to test LCA with offer @@ -91,7 +91,7 @@ test('delegate, undelegate', async t => { rootZone.mapStore('recorder'), marshaller, ); - const makeLocalChainAccountKit = prepareLocalChainAccountKit( + const makeLocalChainAccountKit = prepareLocalOrchestrationAccountKit( rootZone, makeRecorderKit, // @ts-expect-error mocked zcf. use `stake-bld.contract.test.ts` to test LCA with offer @@ -141,7 +141,7 @@ test('transfer', async t => { rootZone.mapStore('recorder'), marshaller, ); - const makeLocalChainAccountKit = prepareLocalChainAccountKit( + const makeLocalChainAccountKit = prepareLocalOrchestrationAccountKit( rootZone, makeRecorderKit, // @ts-expect-error mocked zcf. use `stake-bld.contract.test.ts` to test LCA with offer diff --git a/packages/orchestration/test/types.test-d.ts b/packages/orchestration/test/types.test-d.ts index 8ae786324e8..cfc5989588b 100644 --- a/packages/orchestration/test/types.test-d.ts +++ b/packages/orchestration/test/types.test-d.ts @@ -10,7 +10,7 @@ import type { CosmosValidatorAddress, StakingAccountActions, } from '../src/types.js'; -import type { LocalChainAccountKit } from '../src/exos/local-chain-account-kit.js'; +import type { LocalOrchestrationAccountKit } from '../src/exos/local-orchestration-account.js'; import { prepareCosmosOrchestrationAccount } from '../src/exos/cosmos-orchestration-account.js'; const anyVal = null as any; @@ -36,7 +36,7 @@ expectNotType(chainAddr); } { - const lcak: LocalChainAccountKit = null as any; + const lcak: LocalOrchestrationAccountKit = null as any; const results = await lcak.holder.executeTx([ typedJson('/cosmos.staking.v1beta1.MsgDelegate', { amount: { From 772039ccddf4fa71751e6162b16b6e00cb893f50 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Wed, 19 Jun 2024 08:33:53 -0700 Subject: [PATCH 07/10] refactor: makeLocalOrchestrationAccountKit name --- .../src/examples/stakeBld.contract.js | 4 ++-- .../orchestration/src/exos/orchestrator.js | 11 ++++++++--- packages/orchestration/src/facade.js | 19 ++++++++----------- .../orchestration/src/utils/start-helper.js | 4 ++-- .../local-orchestration-account-kit.test.ts | 12 ++++++------ packages/orchestration/test/facade.test.ts | 2 +- 6 files changed, 27 insertions(+), 25 deletions(-) diff --git a/packages/orchestration/src/examples/stakeBld.contract.js b/packages/orchestration/src/examples/stakeBld.contract.js index 2bb8bb8215a..76f2f411540 100644 --- a/packages/orchestration/src/examples/stakeBld.contract.js +++ b/packages/orchestration/src/examples/stakeBld.contract.js @@ -41,7 +41,7 @@ export const start = async (zcf, privateArgs, baggage) => { privateArgs.marshaller, ); - const makeLocalChainAccountKit = prepareLocalOrchestrationAccountKit( + const makeLocalOrchestrationAccountKit = prepareLocalOrchestrationAccountKit( zone, makeRecorderKit, zcf, @@ -59,7 +59,7 @@ export const start = async (zcf, privateArgs, baggage) => { const account = await V(privateArgs.localchain).makeAccount(); const address = await V(account).getAddress(); // FIXME 'address' is implied by 'account'; use an async maker that get the value itself - return makeLocalChainAccountKit({ + return makeLocalOrchestrationAccountKit({ account, address: harden({ address, diff --git a/packages/orchestration/src/exos/orchestrator.js b/packages/orchestration/src/exos/orchestrator.js index 8c007b7e4dc..c9f9818f8e0 100644 --- a/packages/orchestration/src/exos/orchestrator.js +++ b/packages/orchestration/src/exos/orchestrator.js @@ -50,7 +50,7 @@ export const OrchestratorI = M.interface('Orchestrator', { * asyncFlowTools: AsyncFlowTools; * chainHub: ChainHub; * localchain: Remote; - * makeLocalChainAccountKit: MakeLocalOrchestrationAccountKit; + * makeLocalOrchestrationAccountKit: MakeLocalOrchestrationAccountKit; * makeRecorderKit: MakeRecorderKit; * makeRemoteChainFacade: any; * orchestrationService: Remote; @@ -61,7 +61,12 @@ export const OrchestratorI = M.interface('Orchestrator', { */ export const prepareOrchestrator = ( zone, - { chainHub, localchain, makeLocalChainAccountKit, makeRemoteChainFacade }, + { + chainHub, + localchain, + makeLocalOrchestrationAccountKit, + makeRemoteChainFacade, + }, ) => zone.exoClass( 'Orchestrator', @@ -78,7 +83,7 @@ export const prepareOrchestrator = ( if (name === 'agoric') { return makeLocalChainFacade( localchain, - makeLocalChainAccountKit, + makeLocalOrchestrationAccountKit, agoricChainInfo, ); } diff --git a/packages/orchestration/src/facade.js b/packages/orchestration/src/facade.js index 08f42bbd2bd..da519615093 100644 --- a/packages/orchestration/src/facade.js +++ b/packages/orchestration/src/facade.js @@ -17,20 +17,19 @@ import { prepareOrchestrator } from './exos/orchestrator.js'; * @import {Remote} from '@agoric/internal'; * @import {OrchestrationService} from './service.js'; * @import {Chain, ChainInfo, CosmosChainInfo, IBCConnectionInfo, OrchestrationAccount, Orchestrator} from './types.js'; + * @import {MakeLocalOrchestrationAccountKit} from './exos/local-orchestration-account.js'; */ // FIXME turn this into an Exo /** * @param {Remote} localchain - * @param {ReturnType< - * typeof import('./exos/local-orchestration-account.js').prepareLocalOrchestrationAccountKit - * >} makeLocalChainAccountKit + * @param {MakeLocalOrchestrationAccountKit} makeLocalOrchestrationAccountKit * @param {ChainInfo} localInfo * @returns {Chain} */ export const makeLocalChainFacade = ( localchain, - makeLocalChainAccountKit, + makeLocalOrchestrationAccountKit, localInfo, ) => { return Far('LocalChainFacade', { @@ -42,7 +41,7 @@ export const makeLocalChainFacade = ( async makeAccount() { const lcaP = E(localchain).makeAccount(); const [lca, address] = await Promise.all([lcaP, E(lcaP).getAddress()]); - const { holder: account } = makeLocalChainAccountKit({ + const { holder: account } = makeLocalOrchestrationAccountKit({ account: lca, address: harden({ address, @@ -67,9 +66,7 @@ export const makeLocalChainFacade = ( * orchestrationService: Remote; * localchain: Remote; * chainHub: import('./utils/chainHub.js').ChainHub; - * makeLocalChainAccountKit: ReturnType< - * typeof import('./exos/local-orchestration-account.js').prepareLocalOrchestrationAccountKit - * >; + * makeLocalOrchestrationAccountKit: MakeLocalOrchestrationAccountKit; * makeRecorderKit: MakeRecorderKit; * makeCosmosOrchestrationAccount: any; * makeRemoteChainFacade: any; @@ -84,7 +81,7 @@ export const makeOrchestrationFacade = ({ orchestrationService, localchain, chainHub, - makeLocalChainAccountKit, + makeLocalOrchestrationAccountKit, makeRecorderKit, makeRemoteChainFacade, asyncFlowTools, @@ -95,7 +92,7 @@ export const makeOrchestrationFacade = ({ storageNode && orchestrationService && // @ts-expect-error type says defined but double check - makeLocalChainAccountKit && + makeLocalOrchestrationAccountKit && // @ts-expect-error type says defined but double check makeRecorderKit && makeRemoteChainFacade && @@ -106,7 +103,7 @@ export const makeOrchestrationFacade = ({ asyncFlowTools, chainHub, localchain, - makeLocalChainAccountKit, + makeLocalOrchestrationAccountKit, makeRecorderKit, makeRemoteChainFacade, orchestrationService, diff --git a/packages/orchestration/src/utils/start-helper.js b/packages/orchestration/src/utils/start-helper.js index b9fbbf7cbf6..8cd561daebc 100644 --- a/packages/orchestration/src/utils/start-helper.js +++ b/packages/orchestration/src/utils/start-helper.js @@ -48,7 +48,7 @@ export const provideOrchestration = ( const chainHub = makeChainHub(remotePowers.agoricNames); const { makeRecorderKit } = prepareRecorderKitMakers(baggage, marshaller); - const makeLocalChainAccountKit = prepareLocalOrchestrationAccountKit( + const makeLocalOrchestrationAccountKit = prepareLocalOrchestrationAccountKit( zone, makeRecorderKit, zcf, @@ -79,7 +79,7 @@ export const provideOrchestration = ( zcf, zone, chainHub, - makeLocalChainAccountKit, + makeLocalOrchestrationAccountKit, makeRecorderKit, makeCosmosOrchestrationAccount, makeRemoteChainFacade, diff --git a/packages/orchestration/test/exos/local-orchestration-account-kit.test.ts b/packages/orchestration/test/exos/local-orchestration-account-kit.test.ts index 37b30d2aa55..b3e91a264b3 100644 --- a/packages/orchestration/test/exos/local-orchestration-account-kit.test.ts +++ b/packages/orchestration/test/exos/local-orchestration-account-kit.test.ts @@ -24,7 +24,7 @@ test('deposit, withdraw', async t => { rootZone.mapStore('recorder'), marshaller, ); - const makeLocalChainAccountKit = prepareLocalOrchestrationAccountKit( + const makeLocalOrchestrationAccountKit = prepareLocalOrchestrationAccountKit( rootZone, makeRecorderKit, // @ts-expect-error mocked zcf. use `stake-bld.contract.test.ts` to test LCA with offer @@ -38,7 +38,7 @@ test('deposit, withdraw', async t => { const address = await E(lca).getAddress(); t.log('make a LocalChainAccountKit'); - const { holder: account } = makeLocalChainAccountKit({ + const { holder: account } = makeLocalOrchestrationAccountKit({ account: lca, address: harden({ address, @@ -91,7 +91,7 @@ test('delegate, undelegate', async t => { rootZone.mapStore('recorder'), marshaller, ); - const makeLocalChainAccountKit = prepareLocalOrchestrationAccountKit( + const makeLocalOrchestrationAccountKit = prepareLocalOrchestrationAccountKit( rootZone, makeRecorderKit, // @ts-expect-error mocked zcf. use `stake-bld.contract.test.ts` to test LCA with offer @@ -105,7 +105,7 @@ test('delegate, undelegate', async t => { const address = await E(lca).getAddress(); t.log('make a LocalChainAccountKit'); - const { holder: account } = makeLocalChainAccountKit({ + const { holder: account } = makeLocalOrchestrationAccountKit({ account: lca, address: harden({ address, @@ -141,7 +141,7 @@ test('transfer', async t => { rootZone.mapStore('recorder'), marshaller, ); - const makeLocalChainAccountKit = prepareLocalOrchestrationAccountKit( + const makeLocalOrchestrationAccountKit = prepareLocalOrchestrationAccountKit( rootZone, makeRecorderKit, // @ts-expect-error mocked zcf. use `stake-bld.contract.test.ts` to test LCA with offer @@ -155,7 +155,7 @@ test('transfer', async t => { const address = await E(lca).getAddress(); t.log('make a LocalChainAccountKit'); - const { holder: account } = makeLocalChainAccountKit({ + const { holder: account } = makeLocalOrchestrationAccountKit({ account: lca, address: harden({ address, diff --git a/packages/orchestration/test/facade.test.ts b/packages/orchestration/test/facade.test.ts index bc5e4c915d2..5ccb3206e9a 100644 --- a/packages/orchestration/test/facade.test.ts +++ b/packages/orchestration/test/facade.test.ts @@ -38,7 +38,7 @@ export const mockChainConnection: IBCConnectionInfo = { }, }; -const makeLocalChainAccountKit = () => assert.fail(`not used`); +const makeLocalOrchestrationAccountKit = () => assert.fail(`not used`); test('chain info', async t => { const { bootstrap, facadeServices, commonPrivateArgs } = await commonSetup(t); From 06367457f1dd50effdcbda0a9400f4a1a1aff673 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Wed, 19 Jun 2024 08:43:06 -0700 Subject: [PATCH 08/10] refactor: ChainFacadeI --- .../orchestration/src/exos/orchestrator.js | 20 +++++++------------ .../src/exos/remote-chain-facade.js | 11 ++-------- packages/orchestration/src/typeGuards.js | 15 ++++++++++++++ 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/packages/orchestration/src/exos/orchestrator.js b/packages/orchestration/src/exos/orchestrator.js index c9f9818f8e0..c2dec5b9780 100644 --- a/packages/orchestration/src/exos/orchestrator.js +++ b/packages/orchestration/src/exos/orchestrator.js @@ -5,18 +5,20 @@ import { V } from '@agoric/vow/vat.js'; import { M } from '@endo/patterns'; // eslint-disable-next-line import/no-cycle -- FIXME import { makeLocalChainFacade } from '../facade.js'; +import { + ChainInfoShape, + LocalChainAccountShape, + DenomShape, + BrandInfoShape, + DenomAmountShape, +} from '../typeGuards.js'; /** * @import {Zone} from '@agoric/base-zone'; * @import {ChainHub} from '../utils/chainHub.js'; - * @import {Connection, Port} from '@agoric/network'; - * @import {AnyJson} from '@agoric/cosmic-proto'; - * @import {TxBody} from '@agoric/cosmic-proto/cosmos/tx/v1beta1/tx.js'; - * @import {LocalIbcAddress, RemoteIbcAddress} from '@agoric/vats/tools/ibc-utils.js'; * @import {AsyncFlowTools} from '@agoric/async-flow'; * @import {Vow} from '@agoric/vow'; * @import {TimerService} from '@agoric/time'; - * @import {IBCConnectionID} from '@agoric/vats'; * @import {LocalChain} from '@agoric/vats/src/localchain.js'; * @import {RecorderKit, MakeRecorderKit} from '@agoric/zoe/src/contractSupport/recorder.js'. * @import {Remote} from '@agoric/internal'; @@ -28,14 +30,6 @@ import { makeLocalChainFacade } from '../facade.js'; const { Fail } = assert; const trace = makeTracer('Orchestrator'); -// TODO more validation -export const ChainInfoShape = M.any(); -export const LocalChainAccountShape = M.remotable('LocalChainAccount'); -export const DenomShape = M.string(); -export const BrandInfoShape = M.any(); - -export const DenomAmountShape = { denom: DenomShape, value: M.bigint() }; - /** @see {Orchestrator} */ export const OrchestratorI = M.interface('Orchestrator', { getChain: M.callWhen(M.string()).returns(ChainInfoShape), diff --git a/packages/orchestration/src/exos/remote-chain-facade.js b/packages/orchestration/src/exos/remote-chain-facade.js index 15c70101274..fcb65c1890f 100644 --- a/packages/orchestration/src/exos/remote-chain-facade.js +++ b/packages/orchestration/src/exos/remote-chain-facade.js @@ -1,9 +1,8 @@ /** @file ChainAccount exo */ import { makeTracer } from '@agoric/internal'; import { V } from '@agoric/vow/vat.js'; -import { M } from '@endo/patterns'; -import { ChainInfoShape } from './orchestrator.js'; +import { ChainFacadeI } from '../typeGuards.js'; /** * @import {Zone} from '@agoric/base-zone'; @@ -20,12 +19,6 @@ const trace = makeTracer('RemoteChainFacade'); /** @type {any} */ const anyVal = null; -/** @see {Chain} */ -export const RemoteChainFacadeI = M.interface('RemoteChainFacade', { - getChainInfo: M.callWhen().returns(ChainInfoShape), - makeAccount: M.callWhen().returns(M.remotable('OrchestrationAccount')), -}); - /** * @param {Zone} zone * @param {{ @@ -43,7 +36,7 @@ export const prepareRemoteChainFacade = ( ) => zone.exoClass( 'RemoteChainFacade', - RemoteChainFacadeI, + ChainFacadeI, /** * @param {CosmosChainInfo} remoteChainInfo * @param {IBCConnectionInfo} connectionInfo diff --git a/packages/orchestration/src/typeGuards.js b/packages/orchestration/src/typeGuards.js index e3a836cf2dc..9a4a7391c21 100644 --- a/packages/orchestration/src/typeGuards.js +++ b/packages/orchestration/src/typeGuards.js @@ -77,3 +77,18 @@ export const CosmosChainInfoShape = M.splitRecord( icqEnabled: M.boolean(), }, ); + +// FIXME more validation +export const ChainInfoShape = M.any(); +export const LocalChainAccountShape = M.remotable('LocalChainAccount'); +export const DenomShape = M.string(); +// FIXME more validation +export const BrandInfoShape = M.any(); + +export const DenomAmountShape = { denom: DenomShape, value: M.bigint() }; + +/** @see {Chain} */ +export const ChainFacadeI = M.interface('ChainFacade', { + getChainInfo: M.callWhen().returns(ChainInfoShape), + makeAccount: M.callWhen().returns(M.remotable('OrchestrationAccount')), +}); From bec2253da32663a4717254f4c1872af3a241b5dd Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Wed, 19 Jun 2024 08:51:03 -0700 Subject: [PATCH 09/10] feat: LocalChainFacade exo --- .../src/exos/local-chain-facade.js | 66 +++++++++++++++++++ .../src/exos/local-orchestration-account.js | 2 +- 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 packages/orchestration/src/exos/local-chain-facade.js diff --git a/packages/orchestration/src/exos/local-chain-facade.js b/packages/orchestration/src/exos/local-chain-facade.js new file mode 100644 index 00000000000..c361f328192 --- /dev/null +++ b/packages/orchestration/src/exos/local-chain-facade.js @@ -0,0 +1,66 @@ +/** @file ChainAccount exo */ +import { V } from '@agoric/vow/vat.js'; + +import { ChainFacadeI } from '../typeGuards.js'; + +/** + * @import {Zone} from '@agoric/base-zone'; + * @import {TimerService} from '@agoric/time'; + * @import {Remote} from '@agoric/internal'; + * @import {LocalChain} from '@agoric/vats/src/localchain.js'; + * @import {OrchestrationService} from '../service.js'; + * @import {MakeLocalOrchestrationAccountKit} from './local-orchestration-account.js'; + * @import {ChainInfo, CosmosChainInfo, IBCConnectionInfo, OrchestrationAccount} from '../types.js'; + */ + +/** + * @param {Zone} zone + * @param {{ + * makeLocalOrchestrationAccountKit: MakeLocalOrchestrationAccountKit; + * orchestration: Remote; + * storageNode: Remote; + * timer: Remote; + * localchain: Remote; + * }} powers + */ +export const prepareLocalChainFacade = ( + zone, + { makeLocalOrchestrationAccountKit, localchain, storageNode }, +) => + zone.exoClass( + 'LocalChainFacade', + ChainFacadeI, + /** + * @param {CosmosChainInfo} localChainInfo + */ + localChainInfo => { + return { localChainInfo }; + }, + { + async getChainInfo() { + return this.state.localChainInfo; + }, + + // FIXME parameterize on the remoteChainInfo to make() + // That used to work but got lost in the migration to Exo + /** @returns {Promise>} */ + async makeAccount() { + const { localChainInfo } = this.state; + const lcaP = V(localchain).makeAccount(); + const [lca, address] = await Promise.all([lcaP, V(lcaP).getAddress()]); + const { holder: account } = makeLocalOrchestrationAccountKit({ + account: lca, + address: harden({ + address, + chainId: localChainInfo.chainId, + addressEncoding: 'bech32', + }), + // FIXME storage path + storageNode, + }); + + return account; + }, + }, + ); +harden(prepareLocalChainFacade); diff --git a/packages/orchestration/src/exos/local-orchestration-account.js b/packages/orchestration/src/exos/local-orchestration-account.js index 1f015a580f7..045c176a4c2 100644 --- a/packages/orchestration/src/exos/local-orchestration-account.js +++ b/packages/orchestration/src/exos/local-orchestration-account.js @@ -84,7 +84,7 @@ export const prepareLocalOrchestrationAccountKit = ( * @param {object} initState * @param {LocalChainAccount} initState.account * @param {ChainAddress} initState.address - * @param {StorageNode} initState.storageNode + * @param {Remote} initState.storageNode * @returns {State} */ ({ account, address, storageNode }) => { From 62bdb8aa2f586a1ee824e1e3fff207e0badee8a0 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Wed, 19 Jun 2024 08:57:11 -0700 Subject: [PATCH 10/10] feat: prepareOrchestrator durable returns --- .../src/exos/local-chain-facade.js | 1 + .../orchestration/src/exos/orchestrator.js | 23 +++------ .../src/exos/remote-chain-facade.js | 1 + packages/orchestration/src/facade.js | 50 +++---------------- .../orchestration/src/utils/start-helper.js | 11 ++++ 5 files changed, 29 insertions(+), 57 deletions(-) diff --git a/packages/orchestration/src/exos/local-chain-facade.js b/packages/orchestration/src/exos/local-chain-facade.js index c361f328192..870493c35c8 100644 --- a/packages/orchestration/src/exos/local-chain-facade.js +++ b/packages/orchestration/src/exos/local-chain-facade.js @@ -64,3 +64,4 @@ export const prepareLocalChainFacade = ( }, ); harden(prepareLocalChainFacade); +/** @typedef {ReturnType} MakeLocalChainFacade */ diff --git a/packages/orchestration/src/exos/orchestrator.js b/packages/orchestration/src/exos/orchestrator.js index c2dec5b9780..1ffab8c2613 100644 --- a/packages/orchestration/src/exos/orchestrator.js +++ b/packages/orchestration/src/exos/orchestrator.js @@ -3,8 +3,6 @@ import { AmountShape } from '@agoric/ertp'; import { makeTracer } from '@agoric/internal'; import { V } from '@agoric/vow/vat.js'; import { M } from '@endo/patterns'; -// eslint-disable-next-line import/no-cycle -- FIXME -import { makeLocalChainFacade } from '../facade.js'; import { ChainInfoShape, LocalChainAccountShape, @@ -24,6 +22,8 @@ import { * @import {Remote} from '@agoric/internal'; * @import {OrchestrationService} from '../service.js'; * @import {MakeLocalOrchestrationAccountKit} from './local-orchestration-account.js'; + * @import {MakeLocalChainFacade} from './local-chain-facade.js'; + * @import {MakeRemoteChainFacade} from './remote-chain-facade.js'; * @import {Chain, ChainInfo, CosmosChainInfo, IBCConnectionInfo, OrchestrationAccount, Orchestrator} from '../types.js'; */ @@ -44,9 +44,9 @@ export const OrchestratorI = M.interface('Orchestrator', { * asyncFlowTools: AsyncFlowTools; * chainHub: ChainHub; * localchain: Remote; - * makeLocalOrchestrationAccountKit: MakeLocalOrchestrationAccountKit; * makeRecorderKit: MakeRecorderKit; - * makeRemoteChainFacade: any; + * makeLocalChainFacade: MakeLocalChainFacade; + * makeRemoteChainFacade: MakeRemoteChainFacade; * orchestrationService: Remote; * storageNode: Remote; * timerService: Remote; @@ -55,12 +55,7 @@ export const OrchestratorI = M.interface('Orchestrator', { */ export const prepareOrchestrator = ( zone, - { - chainHub, - localchain, - makeLocalOrchestrationAccountKit, - makeRemoteChainFacade, - }, + { chainHub, localchain, makeLocalChainFacade, makeRemoteChainFacade }, ) => zone.exoClass( 'Orchestrator', @@ -75,11 +70,8 @@ export const prepareOrchestrator = ( const agoricChainInfo = await chainHub.getChainInfo('agoric'); if (name === 'agoric') { - return makeLocalChainFacade( - localchain, - makeLocalOrchestrationAccountKit, - agoricChainInfo, - ); + // @ts-expect-error XXX chainInfo generic + return makeLocalChainFacade(agoricChainInfo); } const remoteChainInfo = await chainHub.getChainInfo(name); @@ -88,6 +80,7 @@ export const prepareOrchestrator = ( remoteChainInfo.chainId, ); + // @ts-expect-error XXX chainInfo generic return makeRemoteChainFacade(remoteChainInfo, connectionInfo); }, makeLocalAccount() { diff --git a/packages/orchestration/src/exos/remote-chain-facade.js b/packages/orchestration/src/exos/remote-chain-facade.js index fcb65c1890f..3ba96ca57fc 100644 --- a/packages/orchestration/src/exos/remote-chain-facade.js +++ b/packages/orchestration/src/exos/remote-chain-facade.js @@ -78,3 +78,4 @@ export const prepareRemoteChainFacade = ( }, ); harden(prepareRemoteChainFacade); +/** @typedef {ReturnType} MakeRemoteChainFacade */ diff --git a/packages/orchestration/src/facade.js b/packages/orchestration/src/facade.js index da519615093..2043346b14f 100644 --- a/packages/orchestration/src/facade.js +++ b/packages/orchestration/src/facade.js @@ -1,9 +1,7 @@ /** @file Orchestration service */ import { Fail } from '@agoric/assert'; -import { V as E } from '@agoric/vow/vat.js'; -import { Far } from '@endo/far'; -// eslint-disable-next-line import/no-cycle -- FIXME + import { prepareOrchestrator } from './exos/orchestrator.js'; /** @@ -17,46 +15,11 @@ import { prepareOrchestrator } from './exos/orchestrator.js'; * @import {Remote} from '@agoric/internal'; * @import {OrchestrationService} from './service.js'; * @import {Chain, ChainInfo, CosmosChainInfo, IBCConnectionInfo, OrchestrationAccount, Orchestrator} from './types.js'; + * @import {MakeLocalChainFacade} from './exos/local-chain-facade.js'; + * @import {MakeRemoteChainFacade} from './exos/remote-chain-facade.js'; * @import {MakeLocalOrchestrationAccountKit} from './exos/local-orchestration-account.js'; */ -// FIXME turn this into an Exo -/** - * @param {Remote} localchain - * @param {MakeLocalOrchestrationAccountKit} makeLocalOrchestrationAccountKit - * @param {ChainInfo} localInfo - * @returns {Chain} - */ -export const makeLocalChainFacade = ( - localchain, - makeLocalOrchestrationAccountKit, - localInfo, -) => { - return Far('LocalChainFacade', { - /** @returns {Promise} */ - async getChainInfo() { - return localInfo; - }, - - async makeAccount() { - const lcaP = E(localchain).makeAccount(); - const [lca, address] = await Promise.all([lcaP, E(lcaP).getAddress()]); - const { holder: account } = makeLocalOrchestrationAccountKit({ - account: lca, - address: harden({ - address, - chainId: localInfo.chainId, - addressEncoding: 'bech32', - }), - // @ts-expect-error TODO: Remote - storageNode: null, - }); - - return account; - }, - }); -}; - /** * @param {{ * zone: Zone; @@ -69,7 +32,8 @@ export const makeLocalChainFacade = ( * makeLocalOrchestrationAccountKit: MakeLocalOrchestrationAccountKit; * makeRecorderKit: MakeRecorderKit; * makeCosmosOrchestrationAccount: any; - * makeRemoteChainFacade: any; + * makeLocalChainFacade: MakeLocalChainFacade; + * makeRemoteChainFacade: MakeRemoteChainFacade; * asyncFlowTools: AsyncFlowTools; * }} powers */ @@ -83,6 +47,7 @@ export const makeOrchestrationFacade = ({ chainHub, makeLocalOrchestrationAccountKit, makeRecorderKit, + makeLocalChainFacade, makeRemoteChainFacade, asyncFlowTools, }) => { @@ -95,6 +60,7 @@ export const makeOrchestrationFacade = ({ makeLocalOrchestrationAccountKit && // @ts-expect-error type says defined but double check makeRecorderKit && + // @ts-expect-error type says defined but double check makeRemoteChainFacade && asyncFlowTools) || Fail`params missing`; @@ -103,8 +69,8 @@ export const makeOrchestrationFacade = ({ asyncFlowTools, chainHub, localchain, - makeLocalOrchestrationAccountKit, makeRecorderKit, + makeLocalChainFacade, makeRemoteChainFacade, orchestrationService, storageNode, diff --git a/packages/orchestration/src/utils/start-helper.js b/packages/orchestration/src/utils/start-helper.js index 8cd561daebc..7b3f2c6fb74 100644 --- a/packages/orchestration/src/utils/start-helper.js +++ b/packages/orchestration/src/utils/start-helper.js @@ -7,6 +7,7 @@ import { makeOrchestrationFacade } from '../facade.js'; import { makeChainHub } from './chainHub.js'; import { prepareRemoteChainFacade } from '../exos/remote-chain-facade.js'; import { prepareCosmosOrchestrationAccount } from '../exos/cosmos-orchestration-account.js'; +import { prepareLocalChainFacade } from '../exos/local-chain-facade.js'; /** * @import {PromiseKit} from '@endo/promise-kit' @@ -75,6 +76,15 @@ export const provideOrchestration = ( timer: remotePowers.timerService, }); + const makeLocalChainFacade = prepareLocalChainFacade(zone, { + makeLocalOrchestrationAccountKit, + localchain: remotePowers.localchain, + // FIXME what path? + storageNode: remotePowers.storageNode, + orchestration: remotePowers.orchestrationService, + timer: remotePowers.timerService, + }); + const facade = makeOrchestrationFacade({ zcf, zone, @@ -82,6 +92,7 @@ export const provideOrchestration = ( makeLocalOrchestrationAccountKit, makeRecorderKit, makeCosmosOrchestrationAccount, + makeLocalChainFacade, makeRemoteChainFacade, asyncFlowTools, ...remotePowers,