Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unify flows and orca #15

Open
wants to merge 2 commits into
base: dev/orca-v1
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified .yarn/install-state.gz
Binary file not shown.
1 change: 1 addition & 0 deletions contract/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
start-sell-concert-tickets-permit.json
start-sell-concert-tickets.js
bundles/
startBasic*
34 changes: 21 additions & 13 deletions contract/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"devDependencies": {
"@agoric/eslint-config": "^0.4.1-upgrade-16-fi-dev-8879538.0",
"@agoric/inter-protocol": "^0.16.2-upgrade-16-fi-dev-8879538.0",
"@agoric/swingset-liveslots": "^0.10.3-u16.1",
"@endo/eslint-plugin": "^0.5.2",
"@endo/far": "1.1.2",
"@endo/ses-ava": "^1.2.2",
Expand All @@ -54,25 +55,32 @@
"typescript-eslint": "^7.13.0"
},
"dependencies": {
"@agoric/async-flow": "0.1.1-dev-9c9e5cf.0",
"@agoric/async-flow": "^0.1.1-dev-ee2126b.0",
"@agoric/cosmic-proto": "dev",
"@agoric/ertp": "dev",
"@agoric/deploy-script-support": "dev",
"@agoric/ertp": "^0.16.2",
"@agoric/governance": "0.10.4-u16.1",
"@agoric/internal": "dev",
"@agoric/internal": "^0.4.0-u16.1",
"@agoric/network": "^0.2.0-u16.1",
"@agoric/notifier": "^0.6.2",
"@agoric/orchestration": "0.1.1-dev-9c9e5cf.0",
"@agoric/store": "0.9.3-u16.0",
"@agoric/time": "dev",
"@agoric/vats": "dev",
"@agoric/vow": "0.1.1-dev-9c9e5cf.0",
"@agoric/zoe": "dev",
"@agoric/zone": "0.2.3-dev-9c9e5cf.0",
"@agoric/store": "0.9.2",
"@agoric/time": "^0.3.2",
"@agoric/vat-data": "^0.5.2",
"@agoric/vats": "^0.16.0-u16.2",
"@agoric/vow": "dev",
"@agoric/zoe": "^0.26.3-u16.1",
"@agoric/zone": "^0.3.0-u16.1",
"@endo/base64": "^1.0.6",
"@endo/bundle-source": "3.2.3",
"@endo/far": "^1.1.2",
"@endo/errors": "^1.2.4",
"@endo/far": "^1.1.4",
"@endo/init": "1.1.2",
"@endo/marshal": "^1.5.0",
"@endo/patterns": "^1.2.0",
"@endo/marshal": "^1.5.2",
"@endo/patterns": "^1.4.2",
"@endo/promise-kit": "^1.1.4",
"@endo/errors": "^1.2.4",
"execa": "^9.2.0",
"fs-extra": "^11.2.0",
"ses": "1.5.0"
},
"ava": {
Expand Down
102 changes: 102 additions & 0 deletions contract/scripts/deploy-flows.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#!/usr/bin/env node
/* global process, fetch, setTimeout */
// @ts-check
import '@endo/init/debug.js';
import { createRequire } from 'module';
import { execa } from 'execa';
import fse from 'fs-extra';
import { execFile, execFileSync } from 'node:child_process';

import { makeNodeBundleCache } from '@endo/bundle-source/cache.js';
import { parseArgs } from 'node:util';
import { makeE2ETools } from '../src/flows/tools/e2e-tools.js';

const nodeRequire = createRequire(import.meta.url);
const { readJSON } = fse;

/** @type {import('node:util').ParseArgsConfig['options']} */
const options = {
help: { type: 'boolean' },
builder: { type: 'string' },
service: { type: 'string', default: 'agd' },
workdir: { type: 'string', default: '/workspace/contract' },
};
/**
* @typedef {{
* help: boolean,
* builder: string,
* service: string,
* workdir: string,
* }} DeployOptions
*/

const Usage = `
deploy-contract [options] [--install <contract>] [--eval <proposal>]...

Options:
--help print usage
--builder proposal builder
--service SVC docker compose service to run agd (default: ${options.service.default}).
Use . to run agd outside docker.
--workdir DIR workdir for docker service (default: ${options.workdir.default})
`;

const main = async (bundleDir = 'bundles') => {
const { argv } = process;
// const { writeFile } = fsp;

const progress = (...args) => console.warn(...args); // stderr

const bundleCache = await makeNodeBundleCache(bundleDir, {}, s => import(s));

/** @type {{ values: DeployOptions }} */
// @ts-expect-error options config ensures type
const { values: flags } = parseArgs({ args: argv.slice(2), options });
if (flags.help) {
progress(Usage);
return;
}

const { builder } = flags;

const tools = await makeE2ETools(console.log, bundleCache, {
execFileSync,
execFile,
fetch,
setTimeout,
});

console.log(`building plan: ${builder}`);
// build the plan
const { stdout } = await execa`agoric run ${builder}`;
console.log({ stdout })
const match = stdout.match(/ (?<name>[-\w]+)-permit.json/);
if (!(match && match.groups)) {
throw new Error('no permit found');
}
const plan = await readJSON(`./${match.groups.name}-plan.json`);
console.log(plan);

console.log('copying files to container');
tools.copyFiles([
nodeRequire.resolve(`../${plan.script}`),
nodeRequire.resolve(`../${plan.permit}`),
...plan.bundles.map(b => b.fileName),
]);

console.log('installing bundles');
await tools.installBundles(
plan.bundles.map(
b => `/tmp/contracts/${b.bundleID}.json`,
),
console.log,
);

console.log('executing proposal');
await tools.runCoreEval({
name: plan.name,
description: `${plan.name} proposal`,
});
};

main().catch(err => console.log(err));
26 changes: 26 additions & 0 deletions contract/src/flows/scripts/init-basic-flows.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { makeHelpers } from '@agoric/deploy-script-support';
import { startBasicFlows } from '../src/proposals/start-basic-flows.js';

/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').CoreEvalBuilder} */
export const defaultProposalBuilder = async ({ publishRef, install }) => {
return harden({
sourceSpec: '../src/proposals/start-basic-flows.js',
getManifestCall: [
'getManifestForContract',
{
installKeys: {
basicFlows: publishRef(
install(
'../src/basic-flows.contract.js',
),
),
},
},
],
});
};

export default async (homeP, endowments) => {
const { writeCoreEval } = await makeHelpers(homeP, endowments);
await writeCoreEval(startBasicFlows.name, defaultProposalBuilder);
};
55 changes: 55 additions & 0 deletions contract/src/flows/src/basic-flows.contract.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* @file Primarily a testing fixture, but also serves as an example of how to
* leverage basic functionality of the Orchestration API with async-flow.
*/
import { InvitationShape } from '@agoric/zoe/src/typeGuards.js';
import { M } from '@endo/patterns';
import { preparePortfolioHolder } from '@agoric/orchestration/src/exos/portfolio-holder-kit.js';
import { withOrchestration } from '@agoric/orchestration/src/utils/start-helper.js';
import * as flows from '@agoric/orchestration/src/examples/basic-flows.flows.js';


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

/**
* @param zcf
* @param {OrchestrationPowers & {
* marshaller;
* }} _privateArgs
* @param {Zone} zone
* @param {OrchestrationTools} tools
*/
const contract = async (
zcf,
_privateArgs,
zone,
{ orchestrateAll },
) => {

const orchFns = orchestrateAll(flows, {});

const publicFacet = zone.exo(
'Basic Flows Public Facet',
M.interface('Basic Flows PF', {
makeOrchAccountInvitation: M.callWhen().returns(InvitationShape),
}),
{
makeOrchAccountInvitation() {
return zcf.makeInvitation(
orchFns.makeOrchAccount,
'Make an Orchestration Account',
);
},
},
);

return { publicFacet };
};

// @ts-ignore
export const start = withOrchestration(contract);

/** @typedef {typeof start} BasicFlowsSF */
94 changes: 94 additions & 0 deletions contract/src/flows/src/proposals/start-basic-flows.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/**
* @file A proposal to start the basic flows contract.
*/
import { makeTracer } from '@agoric/internal';
import { makeStorageNodeChild } from '@agoric/internal/src/lib-chainStorage.js';
import { E } from '@endo/far';

/**
* @import {BasicFlowsSF} from '@agoric/orchestration/src/examples/basic-flows.contract.js';
*/

const trace = makeTracer('StartBasicFlows', true);
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
* contract and proposal files.
*
*/
export const startBasicFlows = async ({
consume: {
agoricNames,
board,
chainStorage,
chainTimerService,
cosmosInterchainService,
localchain,
startUpgradable,
},
installation: {
consume: { [contractName]: installation },
},
instance: {
produce: { [contractName]: produceInstance },
},
}) => {
trace(`start ${contractName}`);
await null;

const storageNode = await makeStorageNodeChild(chainStorage, contractName);
const marshaller = await E(board).getPublishingMarshaller();

const startOpts = {
label: 'basicFlows',
installation,
terms: undefined,
privateArgs: {
agoricNames: await agoricNames,
orchestrationService: await cosmosInterchainService,
localchain: await localchain,
storageNode,
marshaller,
timerService: await chainTimerService,
},
};
const { instance } = await E(startUpgradable)(startOpts);
produceInstance.reset();
produceInstance.resolve(instance);
trace('Done.');
};
harden(startBasicFlows);

export const getManifestForContract = (
{ restoreRef },
{ installKeys, ...options },
) => {
return {
manifest: {
[startBasicFlows.name]: {
consume: {
agoricNames: true,
board: true,
chainStorage: true,
chainTimerService: true,
cosmosInterchainService: true,
localchain: true,
startUpgradable: true,
},
installation: {
consume: { [contractName]: true },
},
instance: {
produce: { [contractName]: true },
},
},
},
installations: {
[contractName]: restoreRef(installKeys[contractName]),
},
options,
};
};
Loading