Skip to content

Commit

Permalink
feat(orchestration): add stakeAtom example contract
Browse files Browse the repository at this point in the history
  • Loading branch information
0xpatrickdev committed Apr 4, 2024
1 parent ba75ed6 commit 82f1901
Show file tree
Hide file tree
Showing 7 changed files with 209 additions and 9 deletions.
37 changes: 36 additions & 1 deletion packages/boot/test/bootstrapTests/test-orchestration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { TestFn } from 'ava';
import { Fail } from '@agoric/assert';
import type { start as stakeBldStart } from '@agoric/orchestration/src/contracts/stakeBld.contract.js';
import type { Instance } from '@agoric/zoe/src/zoeService/utils.js';
import { M, matches } from '@endo/patterns';
import { makeWalletFactoryContext } from './walletFactory.ts';

type DefaultTestContext = Awaited<ReturnType<typeof makeWalletFactoryContext>>;
Expand All @@ -14,7 +15,7 @@ const test: TestFn<DefaultTestContext> = anyTest;
test.before(async t => (t.context = await makeWalletFactoryContext(t)));
test.after.always(t => t.context.shutdown?.());

test('stakeBld', async t => {
test.serial('stakeBld', async t => {
const {
agoricNamesRemotes,
buildProposal,
Expand Down Expand Up @@ -86,3 +87,37 @@ test('stakeBld', async t => {
},
});
});

test.serial('stakeAtom', async t => {
const {
buildProposal,
evalProposal,
runUtils: { EV },
} = t.context;
// TODO move into a vm-config for u15
await evalProposal(
buildProposal('@agoric/builders/scripts/vats/init-network.js'),
);
await evalProposal(
buildProposal('@agoric/builders/scripts/vats/init-orchestration.js'),
);
await evalProposal(
buildProposal('@agoric/builders/scripts/orchestration/init-stakeAtom.js'),
);

const agoricNames = await EV.vat('bootstrap').consumeItem('agoricNames');
const instance = await EV(agoricNames).lookup('instance', 'stakeAtom');
t.truthy(instance, 'stakeAtom instance is available');

const zoe = await EV.vat('bootstrap').consumeItem('zoe');
const publicFacet = await EV(zoe).getPublicFacet(instance);
t.truthy(publicFacet, 'stakeAtom publicFacet is available');

const account = await EV(publicFacet).createAccount();
t.log('account', account);
t.truthy(account, 'createAccount returns an account on ATOM connection');
t.truthy(
matches(account, M.remotable('ChainAccount')),
'account is a remotable',
);
});
34 changes: 34 additions & 0 deletions packages/builders/scripts/orchestration/init-stakeAtom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { makeHelpers } from '@agoric/deploy-script-support';

/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').ProposalBuilder} */
export const defaultProposalBuilder = async (
{ publishRef, install },
options = {},
) => {
const {
hostConnectionId = 'connection-1',
controllerConnectionId = 'connection-0',
} = options;
return harden({
sourceSpec: '@agoric/orchestration/src/proposals/start-stakeAtom.js',
getManifestCall: [
'getManifestForStakeAtom',
{
installKeys: {
stakeAtom: publishRef(
install(
'@agoric/orchestration/src/contracts/stakeAtom.contract.js',
),
),
},
hostConnectionId,
controllerConnectionId,
},
],
});
};

export default async (homeP, endowments) => {
const { writeCoreProposal } = await makeHelpers(homeP, endowments);
await writeCoreProposal('start-stakeAtom', defaultProposalBuilder);
};
52 changes: 52 additions & 0 deletions packages/orchestration/src/contracts/stakeAtom.contract.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// @ts-check
/**
* @file Example contract that uses orchestration
*/

import { makeDurableZone } from '@agoric/zone/durable.js';
import { V as E } from '@agoric/vat-data/vow.js';
import { M } from '@endo/patterns';

/**
* @import * as orchestration from '../types'
* @import * as vatData from '@agoric/vat-data'
*/

/**
* @typedef {{
* hostConnectionId: orchestration.ConnectionId;
* controllerConnectionId: orchestration.ConnectionId;
* }} StakeAtomTerms
*/

/**
*
* @param {ZCF<StakeAtomTerms>} zcf
* @param {{
* orchestration: orchestration.Orchestration;
* }} privateArgs
* @param {vatData.Baggage} baggage
*/
export const start = async (zcf, privateArgs, baggage) => {
const { hostConnectionId, controllerConnectionId } = zcf.getTerms();
const { orchestration } = privateArgs;

const zone = makeDurableZone(baggage);

const publicFacet = zone.exo(
'StakeAtom',
M.interface('StakeAtomI', {
createAccount: M.callWhen().returns(M.remotable('ChainAccount')),
}),
{
async createAccount() {
return E(orchestration).createAccount(
hostConnectionId,
controllerConnectionId,
);
},
},
);

return { publicFacet };
};
20 changes: 12 additions & 8 deletions packages/orchestration/src/orchestration.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ import { M } from '@endo/patterns';
import { makeICAConnectionAddress, parseAddress } from './utils/address.js';
import '@agoric/network/exported.js';

/**
* @import { ConnectionId } from './types';
* @import { Zone } from '@agoric/base-zone';
*/

const { Fail, bare } = assert;
const trace = makeTracer('Orchestration');

Expand Down Expand Up @@ -55,7 +60,7 @@ export const ConnectionHandlerI = M.interface('ConnectionHandler', {
onReceive: M.callWhen(M.any(), M.string()).returns(M.any()),
});

/** @param {import('@agoric/base-zone').Zone} zone */
/** @param {Zone} zone */
const prepareChainAccount = zone =>
zone.exoClassKit(
'ChainAccount',
Expand Down Expand Up @@ -127,17 +132,16 @@ const prepareChainAccount = zone =>
* @param {Connection} connection
* @param {string} localAddr
* @param {string} remoteAddr
* @param {ConnectionHandler} _connectionHandler
*/
async onOpen(connection, localAddr, remoteAddr, _connectionHandler) {
async onOpen(connection, localAddr, remoteAddr) {
trace(`ICA Channel Opened for ${localAddr} at ${remoteAddr}`);
this.state.connection = connection;
this.state.remoteAddress = remoteAddr;
this.state.localAddress = localAddr;
// XXX parseAddress currently throws, should it return '' instead?
this.state.accountAddress = parseAddress(remoteAddr);
},
async onClose(_connection, reason, _connectionHandler) {
async onClose(_connection, reason) {
trace(`ICA Channel closed. Reason: ${reason}`);
// XXX handle connection closing
// XXX is there a scenario where a connection will unexpectedly close? _I think yes_
Expand All @@ -157,7 +161,7 @@ export const OrchestrationI = M.interface('Orchestration', {
});

/**
* @param {import('@agoric/base-zone').Zone} zone
* @param {Zone} zone
* @param {ReturnType<typeof prepareChainAccount>} createChainAccount
*/
const prepareOrchestration = (zone, createChainAccount) =>
Expand Down Expand Up @@ -193,9 +197,9 @@ const prepareOrchestration = (zone, createChainAccount) =>
},
public: {
/**
* @param {import('@agoric/orchestration').ConnectionId} hostConnectionId
* @param {ConnectionId} hostConnectionId
* the counterparty connection_id
* @param {import('@agoric/orchestration').ConnectionId} controllerConnectionId
* @param {ConnectionId} controllerConnectionId
* self connection_id
* @returns {Promise<ChainAccount>}
*/
Expand All @@ -220,7 +224,7 @@ const prepareOrchestration = (zone, createChainAccount) =>
},
);

/** @param {import('@agoric/base-zone').Zone} zone */
/** @param {Zone} zone */
export const prepareOrchestrationTools = zone => {
const createChainAccount = prepareChainAccount(zone);
const makeOrchestration = prepareOrchestration(zone, createChainAccount);
Expand Down
68 changes: 68 additions & 0 deletions packages/orchestration/src/proposals/start-stakeAtom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// @ts-check
import { makeTracer } from '@agoric/internal';
import { E } from '@endo/far';

const trace = makeTracer('StartStakeAtom', true);

/**
* @param {BootstrapPowers & { installation: {consume: {stakeAtom: Installation<import('../contracts/stakeAtom.contract.js').start>}}}} powers
* @param {{options: import('../contracts/stakeAtom.contract.js').StakeAtomTerms}} options
*/
export const startStakeAtom = async (
{
consume: { orchestration, startUpgradable },
installation: {
consume: { stakeAtom },
},
instance: {
produce: { stakeAtom: produceInstance },
},
},
{ options: { hostConnectionId, controllerConnectionId } },
) => {
trace('startStakeAtom', { hostConnectionId, controllerConnectionId });
await null;

/** @type {StartUpgradableOpts<import('../contracts/stakeAtom.contract.js').start>} */
const startOpts = {
label: 'stakeAtom',
installation: stakeAtom,
terms: {
hostConnectionId,
controllerConnectionId,
},
privateArgs: {
orchestration: await orchestration,
},
};

const { instance } = await E(startUpgradable)(startOpts);
produceInstance.resolve(instance);
};
harden(startStakeAtom);

export const getManifestForStakeAtom = (
{ restoreRef },
{ installKeys, ...options },
) => {
return {
manifest: {
[startStakeAtom.name]: {
consume: {
orchestration: true,
startUpgradable: true,
},
installation: {
consume: { stakeAtom: true },
},
instance: {
produce: { stakeAtom: true },
},
},
},
installations: {
stakeAtom: restoreRef(installKeys.stakeAtom),
},
options,
};
};
5 changes: 5 additions & 0 deletions packages/vats/src/core/types-ambient.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ type WellKnownName = {
| 'reserve'
| 'psm'
| 'scaledPriceAuthority'
| 'stakeAtom' // test contract
| 'stakeBld' // test contract
| 'econCommitteeCharter'
| 'priceAggregator';
Expand All @@ -193,6 +194,7 @@ type WellKnownName = {
| 'provisionPool'
| 'reserve'
| 'reserveGovernor'
| 'stakeAtom' // test contract
| 'stakeBld' // test contract
| 'Pegasus';
oracleBrand: 'USD';
Expand Down Expand Up @@ -341,9 +343,12 @@ type ChainBootstrapSpaceT = {
* Vault Factory. ONLY FOR DISASTER RECOVERY
*/
instancePrivateArgs: Map<Instance, unknown>;
localchain: import('@agoric/vats/src/localchain.js').LocalChain;
mints?: MintsVat;
namesByAddress: import('../types.js').NameHub;
namesByAddressAdmin: import('../types.js').NamesByAddressAdmin;
networkVat: NetworkVat;
orchestration: import('@agoric/orchestration/src/orchestration.js').Orchestration;
pegasusConnections: import('@agoric/vats').NameHubKit;
pegasusConnectionsAdmin: import('@agoric/vats').NameAdmin;
priceAuthorityVat: Awaited<PriceAuthorityVat>;
Expand Down
2 changes: 2 additions & 0 deletions packages/vats/src/core/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export const agoricNamesReserved = harden({
econCommitteeCharter: 'Charter for Econ Governance questions',
priceAggregator: 'simple price aggregator',
scaledPriceAuthority: 'scaled price authority',
stakeAtom: 'example ATOM staking contract',
stakeBld: 'example BLD staking contract',
},
instance: {
Expand All @@ -70,6 +71,7 @@ export const agoricNamesReserved = harden({
econCommitteeCharter: 'Charter for Econ Governance questions',
provisionPool: 'Account Provision Pool',
walletFactory: 'Smart Wallet Factory',
stakeAtom: 'example ATOM staking contract',
stakeBld: 'example BLD staking contract',
},
oracleBrand: {
Expand Down

0 comments on commit 82f1901

Please sign in to comment.