Skip to content

Commit

Permalink
refactor: use orchestrateAll
Browse files Browse the repository at this point in the history
Co-Authored-By: Dean Tribble <[email protected]>
  • Loading branch information
turadg and dtribble committed Jul 10, 2024
1 parent daf394d commit 56c16b4
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 69 deletions.
92 changes: 25 additions & 67 deletions packages/orchestration/src/examples/sendAnywhere.contract.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import { makeStateRecord } from '@agoric/async-flow';
import { AmountShape } from '@agoric/ertp';
import { heapVowE } from '@agoric/vow/vat.js';
import { withdrawFromSeat } from '@agoric/zoe/src/contractSupport/zoeHelpers.js';
import { InvitationShape } from '@agoric/zoe/src/typeGuards.js';
import { Fail } from '@endo/errors';
import { E } from '@endo/far';
import { M, mustMatch } from '@endo/patterns';
import { makeResumableAgoricNamesHack } from '../exos/agoric-names-tools.js';
import { M } from '@endo/patterns';
import { CosmosChainInfoShape } from '../typeGuards.js';
import { withOrchestration } from '../utils/start-helper.js';

const { entries } = Object;
import { orchestrationFns } from './sendAnywhereFlows.js';

/**
* @import {TimerService} from '@agoric/time';
Expand All @@ -19,9 +17,7 @@ const { entries } = Object;
* @import {Zone} from '@agoric/zone';
* @import {CosmosChainInfo, IBCConnectionInfo} from '../cosmos-api';
* @import {CosmosInterchainService} from '../exos/cosmos-interchain-service.js';
* @import {Orchestrator} from '../types.js'
* @import {OrchestrationTools} from '../utils/start-helper.js';
* @import {OrchestrationAccount} from '../orchestration-api.js'
*/

/**
Expand All @@ -34,54 +30,6 @@ const { entries } = Object;
* }} OrchestrationPowers
*/

/**
* @param {Orchestrator} orch
* @param {object} ctx
* @param {ZCF} ctx.zcf
* @param {any} ctx.agoricNamesTools TODO Give this a better type
* @param {{ account: OrchestrationAccount<any> | undefined }} ctx.contractState
* @param {ZCFSeat} seat
* @param {object} offerArgs
* @param {string} offerArgs.chainName
* @param {string} offerArgs.destAddr
*/
const sendItFn = async (
orch,
{ zcf, agoricNamesTools, contractState },
seat,
offerArgs,
) => {
mustMatch(offerArgs, harden({ chainName: M.scalar(), destAddr: M.string() }));
const { chainName, destAddr } = offerArgs;
const { give } = seat.getProposal();
const [[kw, amt]] = entries(give);
const { denom } = await agoricNamesTools.findBrandInVBank(amt.brand);
const chain = await orch.getChain(chainName);

if (!contractState.account) {
const agoricChain = await orch.getChain('agoric');
contractState.account = await agoricChain.makeAccount();
console.log('contractState.account', contractState.account);
}

const info = await chain.getChainInfo();
console.log('info', info);
const { chainId } = info;
assert(typeof chainId === 'string', 'bad chainId');
const { [kw]: pmtP } = await withdrawFromSeat(zcf, seat, give);
// #9212 types for chain account helpers
// @ts-expect-error LCA should have .deposit() method
await E.when(pmtP, pmt => contractState.account?.deposit(pmt));
await contractState.account?.transfer(
{ denom, value: amt.value },
{
value: destAddr,
encoding: 'bech32',
chainId,
},
);
};

export const SingleAmountRecord = M.and(
M.recordOf(M.string(), AmountShape, {
numPropertiesLimit: 1,
Expand All @@ -103,26 +51,36 @@ const contract = async (
zcf,
privateArgs,
zone,
{ chainHub, orchestrate, vowTools },
{ chainHub, orchestrateAll, vowTools, zoeTools },
) => {
const agoricNamesTools = makeResumableAgoricNamesHack(zone, {
agoricNames: privateArgs.agoricNames,
vowTools,
});

const contractState = makeStateRecord(
/** @type {{ account: OrchestrationAccount<any> | undefined }} */ {
account: undefined,
},
);

/** @type {OfferHandler} */
const sendIt = orchestrate(
'sendIt',
{ zcf, agoricNamesTools, contractState },
sendItFn,
// TODO should be a provided helper
const findBrandInVBank = vowTools.retriable(
zone,
'findBrandInVBank',
/** @param {Brand} brand */
async brand => {
const { agoricNames } = privateArgs;
const assets = await E(E(agoricNames).lookup('vbankAsset')).values();
const it = assets.find(a => a.brand === brand);
it || Fail`brand ${brand} not in agoricNames.vbankAsset`;
return it;
},
);

// orchestrate uses the names on orchestrationFns to do a "prepare" of the associated behavior
const orchFns = orchestrateAll(orchestrationFns, {
zcf,
contractState,
localTransfer: zoeTools.localTransfer,
findBrandInVBank,
});

const publicFacet = zone.exo(
'Send PF',
M.interface('Send PF', {
Expand All @@ -131,7 +89,7 @@ const contract = async (
{
makeSendInvitation() {
return zcf.makeInvitation(
sendIt,
orchFns.sendIt,
'send',
undefined,
M.splitRecord({ give: SingleAmountRecord }),
Expand Down
59 changes: 59 additions & 0 deletions packages/orchestration/src/examples/sendAnywhereFlows.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { M, mustMatch } from '@endo/patterns';

/**
* @import {Orchestrator, OrchestrationAccount} from '../types.js';
*/

const { entries } = Object;

// in guest file (the orchestration functions)
// the second argument is all the endowments provided

export const orchestrationFns = harden({
/**
* @param {Orchestrator} orch
* @param {object} ctx
* @param {{ account: OrchestrationAccount<any> }} ctx.contractState
* @param {any} ctx.localTransfer
* @param {any} ctx.findBrandInVBank
* @param {ZCFSeat} seat
* @param {{ chainName: string; destAddr: string }} offerArgs
*/
async sendIt(
orch,
{ contractState, localTransfer, findBrandInVBank },
seat,
offerArgs,
) {
mustMatch(
offerArgs,
harden({ chainName: M.scalar(), destAddr: M.string() }),
);
const { chainName, destAddr } = offerArgs;
// NOTE the proposal shape ensures that the `give` is a single asset
const { give } = seat.getProposal();
const [[_kw, amt]] = entries(give);
const { denom } = await findBrandInVBank(amt.brand);
const chain = await orch.getChain(chainName);

if (!contractState.account) {
const agoricChain = await orch.getChain('agoric');
contractState.account = await agoricChain.makeAccount();
}

const info = await chain.getChainInfo();
const { chainId } = info;
assert(typeof chainId === 'string', 'bad chainId');

await localTransfer(seat, contractState.account, give);

await contractState.account.transfer(
{ denom, value: amt.value },
{
value: destAddr,
encoding: 'bech32',
chainId,
},
);
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,10 @@ Generated by [AVA](https://avajs.dev).
unwrapMap: 'Alleged: weakMapStore',
},
contract: {
ResumableAgoricNamesHack_kindHandle: 'Alleged: kind',
'Send CF_kindHandle': 'Alleged: kind',
'Send CF_singleton': 'Alleged: Send CF',
'Send PF_kindHandle': 'Alleged: kind',
'Send PF_singleton': 'Alleged: Send PF',
vbankAssetsByBrand: {},
},
orchestration: {
'Local Orchestration Account Kit_kindHandle': 'Alleged: kind',
Expand All @@ -44,6 +42,10 @@ Generated by [AVA](https://avajs.dev).
1: {
contractState_kindHandle: 'Alleged: kind',
contractState_singleton: 'Alleged: contractState',
findBrandInVBank_kindHandle: 'Alleged: kind',
findBrandInVBank_singleton: 'Alleged: findBrandInVBank',
localTransfer_kindHandle: 'Alleged: kind',
localTransfer_singleton: 'Alleged: localTransfer',
},
},
},
Expand Down
Binary file not shown.

0 comments on commit 56c16b4

Please sign in to comment.