diff --git a/packages/orchestration/src/chain-info.js b/packages/orchestration/src/chain-info.js index 5629e52633a..3c268dad4f6 100644 --- a/packages/orchestration/src/chain-info.js +++ b/packages/orchestration/src/chain-info.js @@ -2,15 +2,76 @@ /** @file temporary static lookup of chain info */ -/** @import {CosmosChainInfo, EthChainInfo} from './types.js'; */ +import { E } from '@endo/far'; + +/** + * @import {CosmosChainInfo, EthChainInfo} from './types.js'; + */ /** @typedef {CosmosChainInfo | EthChainInfo} ChainInfo */ // TODO generate this automatically with a build script drawing on data sources such as https://github.com/cosmos/chain-registry +// XXX inlines the enum values to save the import (entraining cosmic-proto which is megabytes) + export const wellKnownChainInfo = /** @satisfies {Record} */ ( harden({ + agoric: { + chainId: 'agoriclocal', + connections: { + cosmoslocal: { + id: 'connection-1', + client_id: '07-tendermint-3', + counterparty: { + client_id: '07-tendermint-2', + connection_id: 'connection-1', + prefix: { + key_prefix: '', + }, + }, + state: 3 /* IBCConnectionState.STATE_OPEN */, + transferChannel: { + portId: 'transfer', + channelId: 'channel-1', + counterPartyChannelId: 'channel-1', + counterPartyPortId: 'transfer', + ordering: 1 /* Order.ORDER_UNORDERED */, + state: 3 /* IBCConnectionState.STATE_OPEN */, + version: 'ics20-1', + }, + versions: [{ identifier: '', features: ['', ''] }], + delay_period: 0n, + }, + osmosislocal: { + id: 'connection-0', + client_id: '07-tendermint-2', + counterparty: { + client_id: '07-tendermint-2', + connection_id: 'connection-1', + prefix: { + key_prefix: '', + }, + }, + state: 3 /* IBCConnectionState.STATE_OPEN */, + transferChannel: { + portId: 'transfer', + channelId: 'channel-0', + counterPartyChannelId: 'channel-1', + counterPartyPortId: 'transfer', + ordering: 1 /* Order.ORDER_UNORDERED */, + state: 3 /* IBCConnectionState.STATE_OPEN */, + version: 'ics20-1', + }, + versions: [{ identifier: '', features: ['', ''] }], + delay_period: 0n, + }, + }, + ibcHooksEnabled: true, + icaEnabled: true, + icqEnabled: true, + pfmEnabled: true, + }, // https://github.com/cosmos/chain-registry/blob/master/stride/chain.json stride: { chainId: 'stride-1', @@ -50,3 +111,20 @@ export const wellKnownChainInfo = }, }) ); + +/** + * @param {ERef} agoricNamesAdmin + * @param {(...messages: string[]) => void} log + */ +export const registerChainNamespace = async (agoricNamesAdmin, log) => { + const { nameAdmin } = await E(agoricNamesAdmin).provideChild('chain'); + + const registrationPromises = Object.entries(wellKnownChainInfo).map( + async ([name, info]) => { + log(`registering chain ${name}`); + return E(nameAdmin).update(name, info); + }, + ); + + await Promise.all(registrationPromises); +}; diff --git a/packages/orchestration/src/examples/stakeBld.contract.js b/packages/orchestration/src/examples/stakeBld.contract.js index b2ae4d1dfe2..410277d759d 100644 --- a/packages/orchestration/src/examples/stakeBld.contract.js +++ b/packages/orchestration/src/examples/stakeBld.contract.js @@ -10,10 +10,12 @@ 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 { prepareMockChainInfo } from '../utils/mockChainInfo.js'; /** + * @import {NameHub} from '@agoric/vats'; + * @import {Remote} from '@agoric/internal'; * @import {TimerBrand, TimerService} from '@agoric/time'; + * @import {LocalChain} from '@agoric/vats/src/localchain.js'; */ const trace = makeTracer('StakeBld'); @@ -21,7 +23,8 @@ const trace = makeTracer('StakeBld'); /** * @param {ZCF} zcf * @param {{ - * localchain: import('@agoric/vats/src/localchain.js').LocalChain; + * agoricNames: Remote; + * localchain: Remote; * marshaller: Marshaller; * storageNode: StorageNode; * timerService: TimerService; @@ -42,9 +45,12 @@ export const start = async (zcf, privateArgs, baggage) => { privateArgs.marshaller, ); - // Mocked until #8879 - // Would expect this to be instantiated elsewhere, and passed in as a reference - const agoricChainInfo = prepareMockChainInfo(); + // FIXME in a second incarnation we can't make a remote call before defining all kinds + // UNTIL https://github.com/Agoric/agoric-sdk/issues/8879 + const agoricChainInfo = await E(privateArgs.agoricNames).lookup( + 'chain', + 'agoric', + ); const makeLocalChainAccountKit = prepareLocalChainAccountKit( zone, diff --git a/packages/orchestration/src/exos/local-chain-account-kit.js b/packages/orchestration/src/exos/local-chain-account-kit.js index 655c843423c..4b16a61c9f1 100644 --- a/packages/orchestration/src/exos/local-chain-account-kit.js +++ b/packages/orchestration/src/exos/local-chain-account-kit.js @@ -23,9 +23,6 @@ import { dateInSeconds, makeTimestampHelper } from '../utils/time.js'; * @import {TimerService, TimerBrand} from '@agoric/time'; */ -// partial until #8879 -/** @typedef {Pick} AgoricChainInfo */ - const trace = makeTracer('LCAH'); const { Fail } = assert; @@ -66,7 +63,7 @@ const PUBLIC_TOPICS = { * @param {ZCF} zcf * @param {TimerService} timerService * @param {TimerBrand} timerBrand - * @param {AgoricChainInfo} agoricChainInfo + * @param {CosmosChainInfo} agoricChainInfo */ export const prepareLocalChainAccountKit = ( zone, diff --git a/packages/orchestration/src/proposals/start-stakeBld.js b/packages/orchestration/src/proposals/start-stakeBld.js index c3626547c51..86ce07079a5 100644 --- a/packages/orchestration/src/proposals/start-stakeBld.js +++ b/packages/orchestration/src/proposals/start-stakeBld.js @@ -2,6 +2,7 @@ import { makeTracer } from '@agoric/internal'; import { makeStorageNodeChild } from '@agoric/internal/src/lib-chainStorage.js'; import { Stake } from '@agoric/internal/src/tokens.js'; import { E } from '@endo/far'; +import { registerChainNamespace } from '../chain-info.js'; const trace = makeTracer('StartStakeBld', true); @@ -18,6 +19,8 @@ const trace = makeTracer('StartStakeBld', true); */ export const startStakeBld = async ({ consume: { + agoricNames: agoricNamesP, + agoricNamesAdmin, board, chainStorage, chainTimerService: chainTimerServiceP, @@ -37,12 +40,16 @@ export const startStakeBld = async ({ const VSTORAGE_PATH = 'stakeBld'; trace('startStakeBld'); + // Assumes this is the first proposal to need/provide `chain` namespace + await registerChainNamespace(agoricNamesAdmin, trace); + const storageNode = await makeStorageNodeChild(chainStorage, VSTORAGE_PATH); // NB: committee must only publish what it intended to be public const marshaller = await E(board).getPublishingMarshaller(); - const [timerService, timerBrand] = await Promise.all([ + const [agoricNames, timerService, timerBrand] = await Promise.all([ + agoricNamesP, chainTimerServiceP, chainTimerServiceP.then(ts => E(ts).getTimerBrand()), ]); @@ -58,6 +65,8 @@ export const startStakeBld = async ({ issuerKeywordRecord: harden({ In: await stakeIssuer }), terms: {}, privateArgs: { + // BEFOREPUSh populate agoricNames with 'agoric' info and test in a3p + agoricNames, localchain: await localchain, timerService, timerBrand, @@ -76,6 +85,8 @@ export const getManifestForStakeBld = ({ restoreRef }, { installKeys }) => { manifest: { [startStakeBld.name]: { consume: { + agoricNames: true, + agoricNamesAdmin: true, board: true, chainStorage: true, chainTimerService: true, diff --git a/packages/orchestration/src/utils/mockChainInfo.js b/packages/orchestration/src/utils/mockChainInfo.js deleted file mode 100644 index 42cfcca688f..00000000000 --- a/packages/orchestration/src/utils/mockChainInfo.js +++ /dev/null @@ -1,81 +0,0 @@ -/** - * @file Mocked Chain Info object - * - * Until https://github.com/Agoric/agoric-sdk/issues/8879 - * - * Generated using - * https://github.com/Agoric/agoric-sdk/compare/pc/ibc-chain-info - */ -import { - Order, - State as IBCChannelState, -} from '@agoric/cosmic-proto/ibc/core/channel/v1/channel.js'; -import { State as IBCConnectionState } from '@agoric/cosmic-proto/ibc/core/connection/v1/connection.js'; - -/** - * @import {Zone} from '@agoric/zone'; - * @import {CosmosChainInfo, IBCConnectionInfo} from '../cosmos-api.js'; - */ - -/** - * currently keyed by ChainId, as this is what we have available in ChainAddress - * to determine the correct IBCChannelID's for a .transfer() msg. - * - * @type {Record} - */ -const connectionEntries = harden({ - cosmoslocal: { - id: 'connection-1', - client_id: '07-tendermint-3', - counterparty: { - client_id: '07-tendermint-2', - connection_id: 'connection-1', - prefix: { - key_prefix: '', - }, - }, - state: IBCConnectionState.STATE_OPEN, - transferChannel: { - portId: 'transfer', - channelId: 'channel-1', - counterPartyChannelId: 'channel-1', - counterPartyPortId: 'transfer', - ordering: Order.ORDER_UNORDERED, - state: IBCChannelState.STATE_OPEN, - version: 'ics20-1', - }, - versions: [{ identifier: '', features: ['', ''] }], - delay_period: 0n, - }, - osmosislocal: { - id: 'connection-0', - client_id: '07-tendermint-2', - counterparty: { - client_id: '07-tendermint-2', - connection_id: 'connection-1', - prefix: { - key_prefix: '', - }, - }, - state: IBCConnectionState.STATE_OPEN, - transferChannel: { - portId: 'transfer', - channelId: 'channel-0', - counterPartyChannelId: 'channel-1', - counterPartyPortId: 'transfer', - ordering: Order.ORDER_UNORDERED, - state: IBCChannelState.STATE_OPEN, - version: 'ics20-1', - }, - versions: [{ identifier: '', features: ['', ''] }], - delay_period: 0n, - }, -}); - -/** @returns {Pick} */ -export const prepareMockChainInfo = () => { - return harden({ - chainId: 'agoriclocal', - connections: connectionEntries, - }); -}; diff --git a/packages/orchestration/test/examples/stake-bld.contract.test.ts b/packages/orchestration/test/examples/stake-bld.contract.test.ts index 7dc11530e48..d9b75a2d05e 100644 --- a/packages/orchestration/test/examples/stake-bld.contract.test.ts +++ b/packages/orchestration/test/examples/stake-bld.contract.test.ts @@ -13,6 +13,7 @@ type StartFn = typeof import('@agoric/orchestration/src/examples/stakeBld.contract.js').start; const startContract = async ({ + agoricNames, timer, localchain, marshaller, @@ -28,6 +29,7 @@ const startContract = async ({ { In: bld.issuer }, {}, { + agoricNames, localchain, marshaller, storageNode: storage.rootNode, 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 368b1d5489a..46b1a6c0e8e 100644 --- a/packages/orchestration/test/exos/local-chain-account-kit.test.ts +++ b/packages/orchestration/test/exos/local-chain-account-kit.test.ts @@ -5,9 +5,11 @@ import { prepareRecorderKitMakers } from '@agoric/zoe/src/contractSupport/record import { E, Far } from '@endo/far'; import { prepareLocalChainAccountKit } from '../../src/exos/local-chain-account-kit.js'; import { ChainAddress } from '../../src/orchestration-api.js'; -import { prepareMockChainInfo } from '../../src/utils/mockChainInfo.js'; import { NANOSECONDS_PER_SECOND } from '../../src/utils/time.js'; import { commonSetup } from '../supports.js'; +import { wellKnownChainInfo } from '../../src/chain-info.js'; + +const agoricChainInfo = wellKnownChainInfo.agoric; test('deposit, withdraw', async t => { const { bootstrap, brands, utils } = await commonSetup(t); @@ -17,7 +19,6 @@ test('deposit, withdraw', async t => { const { timer, localchain, marshaller, rootZone, storage } = bootstrap; t.log('chainInfo mocked via `prepareMockChainInfo` until #8879'); - const agoricChainInfo = prepareMockChainInfo(); t.log('exo setup - prepareLocalChainAccountKit'); const { makeRecorderKit } = prepareRecorderKitMakers( @@ -84,9 +85,6 @@ test('delegate, undelegate', async t => { const { timer, localchain, marshaller, rootZone, storage } = bootstrap; - t.log('chainInfo mocked via `prepareMockChainInfo` until #8879'); - const agoricChainInfo = prepareMockChainInfo(); - t.log('exo setup - prepareLocalChainAccountKit'); const { makeRecorderKit } = prepareRecorderKitMakers( rootZone.mapStore('recorder'), @@ -135,9 +133,6 @@ test('transfer', async t => { const { timer, localchain, marshaller, rootZone, storage } = bootstrap; - t.log('chainInfo mocked via `prepareMockChainInfo` until #8879'); - const agoricChainInfo = prepareMockChainInfo(); - t.log('exo setup - prepareLocalChainAccountKit'); const { makeRecorderKit } = prepareRecorderKitMakers( rootZone.mapStore('recorder'), diff --git a/packages/orchestration/test/supports.ts b/packages/orchestration/test/supports.ts index b87f4678bb7..0989d18f096 100644 --- a/packages/orchestration/test/supports.ts +++ b/packages/orchestration/test/supports.ts @@ -15,7 +15,10 @@ import { fakeNetworkEchoStuff } from './network-fakes.js'; import { prepareOrchestrationTools } from '../src/service.js'; import { CHAIN_KEY } from '../src/facade.js'; import type { CosmosChainInfo } from '../src/cosmos-api.js'; -import { wellKnownChainInfo } from '../src/chain-info.js'; +import { + registerChainNamespace, + wellKnownChainInfo, +} from '../src/chain-info.js'; export { makeFakeLocalchainBridge } from '@agoric/vats/tools/fake-bridge.js'; @@ -60,15 +63,8 @@ export const commonSetup = async t => { const { nameHub: agoricNames, nameAdmin: agoricNamesAdmin } = makeNameHubKit(); - const spaces = await makeWellKnownSpaces(agoricNamesAdmin, t.log, [ - CHAIN_KEY, - ]); - // Simulate what BLD stakers would have configured - for (const [name, info] of Object.entries(wellKnownChainInfo)) { - // @ts-expect-error FIXME types - spaces.chain.produce[name].resolve(info); - } + await registerChainNamespace(agoricNamesAdmin, t.log); return { bootstrap: {