A portfolio holder stores two or more OrchestrationAccounts and combines ContinuingOfferResult's from each into a single result.

The invitationMakers can be accessed via the Proxy invitationMaker, which calls out to other invitationMakers.

See MakeCombineInvitationMakers for an exo that allows a developer to define extra invitationMakers to combine with platform-provided ones.

// in contract start/prepare
const makePortfolioHolder = preparePortfolioHolder(
rootZone.subZone('portfolio'),
vowTools,
);

// in a flow
const accounts = {
cosmoshub: await cosmosChain.makeAccount(),
agoric: await agoricChain.makeAccount(),
};
const accountEntries = harden(Object.entries(accounts));
const publicTopicEntries = harden(
await Promise.all(
Object.entries(accounts).map(async ([chainName, holder]) => {
const { account } = await E(holder).getPublicTopics();
return [chainName, account];
}),
),
);
const holder = makePortfolioHolder(accountEntries, publicTopicEntries);

// return ContinuingOfferResult to client
return E(holder).asContinuingOffer();

const { invitationMakers } = await E(holder).asContinuingOffer();

// with invitationArgs
const delegateInv = await E(invitationMakers).Proxying(
'cosmoshub',
'Delegate',
[
{
value: 'cosmos1valoper',
chainId: 'cosmoshub-99',
encoding: 'bech32',
},
{
denom: 'uatom',
value: 10n,
},
],
);

// without invitationArgs
const transferInv = await E(invitationMakers).Proxying(
'cosmoshub',
'Transfer',
);
  • Parameters

    • zone: Zone
    • vowTools: VowTools

    Returns ((...args: [accountEntries: Iterable<[string, OrchestrationAccount<any>], any, any>, publicTopicEntries: Iterable<[string, ResolvedPublicTopic<unknown>], any, any>]) => Guarded<{
        addAccount(chainName: string, account: HostInterface<OrchestrationAccount<any>>, publicTopic: ResolvedPublicTopic<unknown>): Vow<void>;
        asContinuingOffer(): Vow<{
            invitationMakers: Guarded<{
                Proxying<IA>(chainName: string, action: string, invitationArgs?: IA): Promise<Invitation<unknown, IA>>;
            }>;
            publicSubscribers: {
                [k: string]: T;
            };
        }>;
        getAccount(chainName: string): Vow<HostInterface<OrchestrationAccountI>>;
        getPublicTopics(): Vow<{
            [k: string]: T;
        }>;
    }>)

      • (...args): Guarded<{
            addAccount(chainName: string, account: HostInterface<OrchestrationAccount<any>>, publicTopic: ResolvedPublicTopic<unknown>): Vow<void>;
            asContinuingOffer(): Vow<{
                invitationMakers: Guarded<{
                    Proxying<IA>(chainName: string, action: string, invitationArgs?: IA): Promise<Invitation<unknown, IA>>;
                }>;
                publicSubscribers: {
                    [k: string]: T;
                };
            }>;
            getAccount(chainName: string): Vow<HostInterface<OrchestrationAccountI>>;
            getPublicTopics(): Vow<{
                [k: string]: T;
            }>;
        }>
      • Parameters

        Returns Guarded<{
            addAccount(chainName: string, account: HostInterface<OrchestrationAccount<any>>, publicTopic: ResolvedPublicTopic<unknown>): Vow<void>;
            asContinuingOffer(): Vow<{
                invitationMakers: Guarded<{
                    Proxying<IA>(chainName: string, action: string, invitationArgs?: IA): Promise<Invitation<unknown, IA>>;
                }>;
                publicSubscribers: {
                    [k: string]: T;
                };
            }>;
            getAccount(chainName: string): Vow<HostInterface<OrchestrationAccountI>>;
            getPublicTopics(): Vow<{
                [k: string]: T;
            }>;
        }>