Skip to content

Commit

Permalink
feat: basic-flows.contract.js seed chainHub
Browse files Browse the repository at this point in the history
- basic-flows.contract.js is provided with chainInfo and assetInfo in privateArgs via builder options
- needed for tests that use localAccount.transfer(), now reliant on asset info, to pass
  • Loading branch information
0xpatrickdev committed Nov 28, 2024
1 parent 90b2603 commit 9c0a243
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 36 deletions.
81 changes: 70 additions & 11 deletions packages/boot/test/bootstrapTests/orchestration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,17 @@ import {
defaultMarshaller,
documentStorageSchema,
} from '@agoric/internal/src/storage-test-utils.js';
import type { CosmosValidatorAddress } from '@agoric/orchestration';
import {
withChainCapabilities,
type CosmosValidatorAddress,
} from '@agoric/orchestration';
import type { start as startStakeIca } from '@agoric/orchestration/src/examples/stake-ica.contract.js';
import type { Instance } from '@agoric/zoe/src/zoeService/utils.js';
import type { TestFn } from 'ava';
import { SIMULATED_ERRORS } from '@agoric/vats/tools/fake-bridge.js';
import fetchedChainInfo from '@agoric/orchestration/src/fetched-chain-info.js';
import { buildVTransferEvent } from '@agoric/orchestration/tools/ibc-mocks.js';
import { BridgeId } from '@agoric/internal';
import {
makeWalletFactoryContext,
type WalletFactoryTestContext,
Expand Down Expand Up @@ -290,11 +296,32 @@ test.serial('basic-flows', async t => {
evalProposal,
agoricNamesRemotes,
readPublished,
bridgeUtils: { flushInboundQueue },
bridgeUtils: { flushInboundQueue, runInbound },
} = t.context;

await evalProposal(
buildProposal('@agoric/builders/scripts/orchestration/init-basic-flows.js'),
buildProposal(
'@agoric/builders/scripts/orchestration/init-basic-flows.js',
[
'--chainInfo',
JSON.stringify(withChainCapabilities(fetchedChainInfo)),
'--assetInfo',
JSON.stringify({
'ibc/uusdconagoric': {
chainName: 'agoric',
baseName: 'noble',
baseDenom: 'uusdc',
},
// not tested until #10006. consider renaming to ibc/uusdconcosmos
// and updating boot/tools/ibc/mocks.ts
'ibc/uusdchash': {
chainName: 'cosmoshub',
baseName: 'noble',
baseDenom: 'uusdc',
},
}),
],
),
);

const wd =
Expand Down Expand Up @@ -416,20 +443,37 @@ test.serial('basic-flows', async t => {
},
proposal: {},
offerArgs: {
amount: { denom: 'ibc/uusdchash', value: 10n },
amount: { denom: 'ibc/uusdconagoric', value: 10n },
destination: {
chainId: 'noble-1',
value: 'noble1test',
encoding: 'bech32,',
},
},
});
t.like(wd.getLatestUpdateRecord(), {
status: {
id: 'transfer-to-noble-from-agoric',
error: undefined,
},

await runInbound(
BridgeId.VTRANSFER,
buildVTransferEvent({
sourceChannel: 'channel-62',
sequence: '1',
}),
);

const latestOfferStatus = () => {
const curr = wd.getLatestUpdateRecord();
if (curr.updated === 'offerStatus') {
return curr.status;
}
throw new Error('expected updated to be "offerStatus"');
};

const offerResult = latestOfferStatus();
t.like(offerResult, {
id: 'transfer-to-noble-from-agoric',
error: undefined,
});
t.true('result' in offerResult, 'transfer vow settled');

await t.throwsAsync(
wd.executeOffer({
Expand All @@ -441,7 +485,7 @@ test.serial('basic-flows', async t => {
},
proposal: {},
offerArgs: {
amount: { denom: 'ibc/uusdchash', value: SIMULATED_ERRORS.TIMEOUT },
amount: { denom: 'ibc/uusdconagoric', value: SIMULATED_ERRORS.TIMEOUT },
destination: {
chainId: 'noble-1',
value: 'noble1test',
Expand Down Expand Up @@ -472,7 +516,22 @@ test.serial('basic-flows - portfolio holder', async t => {
} = t.context;

await evalProposal(
buildProposal('@agoric/builders/scripts/orchestration/init-basic-flows.js'),
buildProposal(
'@agoric/builders/scripts/orchestration/init-basic-flows.js',
[
'--chainInfo',
JSON.stringify(withChainCapabilities(fetchedChainInfo)),
'--assetInfo',
JSON.stringify({
ubld: {
chainName: 'agoric',
baseName: 'agoric',
baseDenom: 'ubld',
brandKey: 'BLD',
},
}),
],
),
);

const wd =
Expand Down
44 changes: 42 additions & 2 deletions packages/builders/scripts/orchestration/init-basic-flows.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
import { makeHelpers } from '@agoric/deploy-script-support';
import { startBasicFlows } from '@agoric/orchestration/src/proposals/start-basic-flows.js';
import { parseArgs } from 'node:util';

/**
* @import {ParseArgsConfig} from 'node:util'
*/

/** @type {ParseArgsConfig['options']} */
const parserOpts = {
chainInfo: { type: 'string' },
assetInfo: { type: 'string' },
};

/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').CoreEvalBuilder} */
export const defaultProposalBuilder = async ({ publishRef, install }) => {
export const defaultProposalBuilder = async (
{ publishRef, install },
options,
) => {
return harden({
sourceSpec: '@agoric/orchestration/src/proposals/start-basic-flows.js',
getManifestCall: [
Expand All @@ -15,13 +29,39 @@ export const defaultProposalBuilder = async ({ publishRef, install }) => {
),
),
},
options,
},
],
});
};

/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').DeployScriptFunction} */
export default async (homeP, endowments) => {
const { scriptArgs } = endowments;

const {
values: { chainInfo, assetInfo },
} = parseArgs({
args: scriptArgs,
options: parserOpts,
});

const parseChainInfo = () => {
if (typeof chainInfo !== 'string') return undefined;
return JSON.parse(chainInfo);
};
const parseAssetInfo = () => {
if (typeof assetInfo !== 'string') return undefined;
return JSON.parse(assetInfo);
};
const opts = harden({
chainInfo: parseChainInfo(),
assetInfo: parseAssetInfo(),
});

const { writeCoreEval } = await makeHelpers(homeP, endowments);
await writeCoreEval(startBasicFlows.name, defaultProposalBuilder);

await writeCoreEval(startBasicFlows.name, utils =>
defaultProposalBuilder(utils, opts),
);
};
17 changes: 14 additions & 3 deletions packages/orchestration/src/examples/basic-flows.contract.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,30 @@ import { InvitationShape } from '@agoric/zoe/src/typeGuards.js';
import { M } from '@endo/patterns';
import { preparePortfolioHolder } from '../exos/portfolio-holder-kit.js';
import { withOrchestration } from '../utils/start-helper.js';
import { registerChainsAndAssets } from '../utils/chain-hub-helper.js';
import * as flows from './basic-flows.flows.js';

/**
* @import {Zone} from '@agoric/zone';
* @import {CosmosChainInfo, Denom, DenomDetail} from '@agoric/orchestration';
* @import {OrchestrationPowers, OrchestrationTools} from '../utils/start-helper.js';
*/

/**
* @param {ZCF} zcf
* @param {OrchestrationPowers & {
* marshaller: Marshaller;
* }} _privateArgs
* chainInfo?: Record<string, CosmosChainInfo>;
* assetInfo?: Record<Denom, DenomDetail & { brandKey?: string }>;
* }} privateArgs
* @param {Zone} zone
* @param {OrchestrationTools} tools
*/
const contract = async (
zcf,
_privateArgs,
privateArgs,
zone,
{ orchestrateAll, vowTools },
{ chainHub, orchestrateAll, vowTools },
) => {
const makePortfolioHolder = preparePortfolioHolder(
zone.subZone('portfolio'),
Expand Down Expand Up @@ -56,6 +60,13 @@ const contract = async (
},
);

registerChainsAndAssets(
chainHub,
zcf.getTerms().brands,
privateArgs.chainInfo,
privateArgs.assetInfo,
);

return { publicFacet };
};

Expand Down
62 changes: 42 additions & 20 deletions packages/orchestration/src/proposals/start-basic-flows.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { makeStorageNodeChild } from '@agoric/internal/src/lib-chainStorage.js';
import { E } from '@endo/far';

/**
* @import {CosmosChainInfo, Denom, DenomDetail} from '@agoric/orchestration';
* @import {BasicFlowsSF} from '../examples/basic-flows.contract.js';
*/

Expand All @@ -15,30 +16,43 @@ const contractName = 'basicFlows';
/**
* See `@agoric/builders/builders/scripts/orchestration/init-basic-flows.js` for
* the accompanying proposal builder. Run `agoric run
* packages/builders/scripts/orchestration/init-basic-flows.js` to build the
* packages/builders/scripts/orchestration/init-basic-flows.js --chainInfo
* 'chainName:CosmosChainInfo' --assetInfo 'denom:DenomDetail'` to build the
* contract and proposal files.
*
* @param {BootstrapPowers} powers
* @param {{
* options: {
* chainInfo: Record<string, CosmosChainInfo>;
* assetInfo: Record<Denom, DenomDetail & { brandKey?: string }>;
* };
* }} config
*/
export const startBasicFlows = async ({
consume: {
agoricNames,
board,
chainStorage,
chainTimerService,
cosmosInterchainService,
localchain,
startUpgradable,
},
installation: {
// @ts-expect-error not a WellKnownName
consume: { [contractName]: installation },
},
instance: {
// @ts-expect-error not a WellKnownName
produce: { [contractName]: produceInstance },
export const startBasicFlows = async (
{
consume: {
agoricNames,
board,
chainStorage,
chainTimerService,
cosmosInterchainService,
localchain,
startUpgradable,
},
installation: {
// @ts-expect-error not a WellKnownName
consume: { [contractName]: installation },
},
instance: {
// @ts-expect-error not a WellKnownName
produce: { [contractName]: produceInstance },
},
issuer: {
consume: { BLD },
},
},
}) => {
{ options: { chainInfo, assetInfo } },
) => {
trace(`start ${contractName}`);
await null;

Expand All @@ -49,6 +63,9 @@ export const startBasicFlows = async ({
const startOpts = {
label: 'basicFlows',
installation,
issuerKeywordRecord: {
BLD: await BLD,
},
terms: undefined,
privateArgs: {
agoricNames: await agoricNames,
Expand All @@ -57,6 +74,8 @@ export const startBasicFlows = async ({
storageNode,
marshaller,
timerService: await chainTimerService,
chainInfo,
assetInfo,
},
};

Expand All @@ -67,7 +86,7 @@ harden(startBasicFlows);

export const getManifestForContract = (
{ restoreRef },
{ installKeys, ...options },
{ installKeys, options },
) => {
return {
manifest: {
Expand All @@ -87,6 +106,9 @@ export const getManifestForContract = (
instance: {
produce: { [contractName]: true },
},
issuer: {
consume: { BLD: true },
},
},
},
installations: {
Expand Down

0 comments on commit 9c0a243

Please sign in to comment.