From bc558d07c051d560c0e17e61b1e99609d27c63c3 Mon Sep 17 00:00:00 2001 From: 0xPatrick Date: Wed, 31 Jul 2024 21:10:19 -0400 Subject: [PATCH] feat: combine-invitation-makers exo - Takes two or more InvitationMaker exos and combines them into a new one. - Useful for combining exos that are already instantiated --- .../src/exos/combine-invitation-makers.js | 71 +++++++++++++++++++ .../src/exos/cosmos-orchestration-account.js | 27 +++---- .../src/utils/orchestrationAccount.js | 18 +++++ 3 files changed, 97 insertions(+), 19 deletions(-) create mode 100644 packages/orchestration/src/exos/combine-invitation-makers.js diff --git a/packages/orchestration/src/exos/combine-invitation-makers.js b/packages/orchestration/src/exos/combine-invitation-makers.js new file mode 100644 index 00000000000..ffb57dbf13a --- /dev/null +++ b/packages/orchestration/src/exos/combine-invitation-makers.js @@ -0,0 +1,71 @@ +import { M } from '@endo/patterns'; +import { + prepareGuardedAttenuator, + makeSyncMethodCallback, +} from '@agoric/internal/src/callback.js'; +import { getMethodNames } from '@agoric/internal'; +import { orchestrationAccountInvitationMakers } from '../utils/orchestrationAccount.js'; + +/** + * @import {MakeAttenuator} from '@agoric/internal/src/callback.js'; + * @import {InvitationMakers} from '@agoric/smart-wallet/src/types.js'; + * @import {Zone} from '@agoric/zone'; + * @import {MethodGuard} from '@endo/patterns'; + * @import {CosmosOrchestrationAccountKit} from './cosmos-orchestration-account.js'; + */ + +/** + * XXX parameterize this in `prepareGuardedAttenuator` + * + * @typedef {{ + * Restake: ( + * validator: import('../cosmos-api.js').CosmosValidatorAddress, + * opts: import('../examples/restake.kit.js').RepeaterOpts, + * ) => Promise; + * CancelRestake: () => Promise; + * }} NewMethods + */ + +/** + * Takes two or more InvitationMaker exos and combines them into a new one. + * + * @param {Zone} zone + * @param {Record} methodGuards + */ +export const prepareCombineInvitationMakers = (zone, methodGuards) => { + const CombinedInterfaceGuard = M.interface('ResolvedContinuingOfferResult', { + ...orchestrationAccountInvitationMakers, + ...methodGuards, + }); + + /** + * @typedef {CosmosOrchestrationAccountKit['invitationMakers']} CosmosOrchAccountInvMakers + */ + + // @ts-expect-error Index signature for type 'string' is missing in type + /** @type {MakeAttenuator} */ + const mixin = prepareGuardedAttenuator(zone, CombinedInterfaceGuard, { + tag: 'CombinedInvitationMakers', + }); + + /** + * @param {...InvitationMakers} invitationMakers + */ + const combineInvitationMakers = (...invitationMakers) => { + const overrides = {}; + for (const invMakers of invitationMakers) { + // remove '__getInterfaceGuard__', '__getMethodNames__' + const names = getMethodNames(invMakers).filter(n => !n.startsWith('__')); + for (const key of names) { + overrides[key] = makeSyncMethodCallback(invMakers, key); + } + } + return mixin({ + overrides, + }); + }; + + return combineInvitationMakers; +}; + +/** @typedef {ReturnType} MakeCombineInvitationMakers */ diff --git a/packages/orchestration/src/exos/cosmos-orchestration-account.js b/packages/orchestration/src/exos/cosmos-orchestration-account.js index 47d4f792d45..80738124585 100644 --- a/packages/orchestration/src/exos/cosmos-orchestration-account.js +++ b/packages/orchestration/src/exos/cosmos-orchestration-account.js @@ -33,7 +33,10 @@ import { } from '../typeGuards.js'; import { coerceCoin, coerceDenom } from '../utils/amounts.js'; import { maxClockSkew, tryDecodeResponse } from '../utils/cosmos.js'; -import { orchestrationAccountMethods } from '../utils/orchestrationAccount.js'; +import { + orchestrationAccountInvitationMakers, + orchestrationAccountMethods, +} from '../utils/orchestrationAccount.js'; import { makeTimestampHelper } from '../utils/time.js'; /** @@ -169,24 +172,10 @@ export const prepareCosmosOrchestrationAccountKit = ( .returns(Vow$(M.record())), }), holder: IcaAccountHolderI, - invitationMakers: M.interface('invitationMakers', { - Delegate: M.call(ChainAddressShape, AmountArgShape).returns( - M.promise(), - ), - Redelegate: M.call( - ChainAddressShape, - ChainAddressShape, - AmountArgShape, - ).returns(M.promise()), - WithdrawReward: M.call(ChainAddressShape).returns(M.promise()), - Undelegate: M.call(M.arrayOf(DelegationShape)).returns(M.promise()), - DeactivateAccount: M.call().returns(M.promise()), - ReactivateAccount: M.call().returns(M.promise()), - TransferAccount: M.call().returns(M.promise()), - Send: M.call().returns(M.promise()), - SendAll: M.call().returns(M.promise()), - Transfer: M.call().returns(M.promise()), - }), + invitationMakers: M.interface( + 'invitationMakers', + orchestrationAccountInvitationMakers, + ), }, /** * @param {object} info diff --git a/packages/orchestration/src/utils/orchestrationAccount.js b/packages/orchestration/src/utils/orchestrationAccount.js index 242482bce60..6c74a591733 100644 --- a/packages/orchestration/src/utils/orchestrationAccount.js +++ b/packages/orchestration/src/utils/orchestrationAccount.js @@ -6,6 +6,7 @@ import { M } from '@endo/patterns'; import { AmountArgShape, ChainAddressShape, + DelegationShape, DenomAmountShape, IBCTransferOptionsShape, } from '../typeGuards.js'; @@ -38,3 +39,20 @@ export const orchestrationAccountMethods = { ), getPublicTopics: M.call().returns(Vow$(TopicsRecordShape)), }; + +export const orchestrationAccountInvitationMakers = { + Delegate: M.call(ChainAddressShape, AmountArgShape).returns(M.promise()), + Redelegate: M.call( + ChainAddressShape, + ChainAddressShape, + AmountArgShape, + ).returns(M.promise()), + WithdrawReward: M.call(ChainAddressShape).returns(M.promise()), + Undelegate: M.call(M.arrayOf(DelegationShape)).returns(M.promise()), + DeactivateAccount: M.call().returns(M.promise()), + ReactivateAccount: M.call().returns(M.promise()), + TransferAccount: M.call().returns(M.promise()), + Send: M.call().returns(M.promise()), + SendAll: M.call().returns(M.promise()), + Transfer: M.call().returns(M.promise()), +};