Skip to content

Commit f016732

Browse files
authored
Merge pull request #1271 from Agoric/ms/update-orch-docs
Orch Docs Landing Page Clarity, Add transactional vs portfolio
2 parents 225e91a + f1b6b5c commit f016732

File tree

4 files changed

+265
-19
lines changed

4 files changed

+265
-19
lines changed

Diff for: main/.vitepress/config.mjs

+4
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ export default defineConfig({
128128
text: 'What is Agoric Orchestration?',
129129
link: '/guides/orchestration/',
130130
},
131+
{
132+
text: 'Transactional vs Portfolio',
133+
link: '/guides/orchestration/txvsportfolio',
134+
},
131135
{
132136
text: 'Key Concepts and APIs',
133137
link: '/guides/orchestration/key-concepts',

Diff for: main/.vitepress/themeConfig/nav.js

+4
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ export const nav = [
1313
text: 'What is Agoric Orchestration?',
1414
link: '/guides/orchestration/',
1515
},
16+
{
17+
text: 'Transactional vs Portfolio',
18+
link: '/guides/orchestration/txvsportfolio',
19+
},
1620
{
1721
text: 'Key Concepts and APIs',
1822
link: '/guides/orchestration/key-concepts',

Diff for: main/guides/orchestration/index.md

+90-19
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,104 @@
11
# What is Agoric Orchestration?
22

3-
Agoric’s Orchestration capability allows developers to easily build cross-chain interactions into existing applications or to create novel cross-chain-focused products.
3+
Agoric's [Orchestration SDK](https://github.com/Agoric/agoric-sdk/tree/master/packages/orchestration) allows developers to easily build cross-chain
4+
interactions into existing applications or to create novel cross-chain-focused
5+
products.
46

5-
The Agoric Orchestration API sits on top of Agoric’s novel VM that provides three key elements that make multichain applications possible:
7+
<br/>
8+
<img src="./assets/chains.png" width="100%" alt="Diagram showing cross-chain interactions through Agoric orchestration" />
9+
<!-- This figure was drawn with canva which does not export SVG format. -->
10+
<br/>
611

7-
- **Remote account control and transfer**: Use the Orchestration APIs to easily create accounts on remote chains, transfer assets, and invoke contracts. Your Agoric contract orchestrates all behavior directly.
8-
- **Multiblock execution with `async` and `await`**: Agoric applications communicate asynchronously and await responses which may come in the same block or many blocks (or weeks!) later. Contracts simply continue executing when the response arrives.
9-
- **On-chain Timers**: Contracts can set timers for regular execution which makes executing common activities like subscriptions easy.
12+
**From a developer's perspective**, your contract or dapp can coordinate actions across
13+
multiple chains without burdening the user to jump through multiple UIs or signing
14+
steps. The Orchestration API _handles the complexity behind the scenes_. This
15+
empowers smart contracts to, for example,
1016

11-
Agoric’s Orchestration APIs simplify controlling accounts on remote chains, moving assets, and using capabilities on any chain the API reaches.
17+
:::tip Key Orchestration Use Cases
1218

13-
<br/>
14-
<img src="./assets/chains.png" width="100%" />
15-
<br/>
19+
- **Perform Inter-Chain Staking** 🌐
20+
Leverage delegated proof-of-stake opportunities on remote Cosmos chains.
1621

17-
## Orchestration Overview
22+
- **Automate Multi-Hop Transfers** 🚀
23+
Bridge tokens from Ethereum to Stride, then stake them or perform actions on
24+
Osmosis.
1825

19-
Agoric's Orchestration API is a tool to help developers build seamless applications out of disparate interoperable chains and services. This composability allows for the development of user-centric applications that leverage the unique strengths of different blockchain ecosystems.
26+
- **Support Scheduled Operations**
27+
Enable recurring and delayed tasks like rent collection and subscription services
28+
through the on-chain Timer Service.
29+
:::
2030

21-
The Agoric Orchestration API simplifies interactions between multiple networks, particularly those using the [Inter-Blockchain Communication (IBC)](/glossary/#ibc) protocol within Cosmos. The API acts as an abstraction layer, streamlining multi-step processes.
31+
The Orchestration API sits on top of Agoric's novel VM that provides three key
32+
elements that make multichain applications possible:
2233

23-
Orchestration integrates with existing Agoric components ([SwingSet](/guides/platform/#swingset), Cosmos modules) and introduces vat-orchestration. This [vat](/glossary/#vat) manages Inter-Chain Account (ICA) identities and connections to host chains, ensuring proper transaction authorization.
34+
- **Remote account control and transfer**: Use the Orchestration APIs to easily
35+
create accounts on remote chains, transfer assets, and invoke contracts. Your
36+
Agoric contract orchestrates all behavior directly.
37+
- **Multiblock execution with `async` and `await`**: Agoric applications
38+
communicate asynchronously and await responses which may come in the same block
39+
or many blocks (or weeks!) later. Contracts simply continue executing when the
40+
response arrives.
41+
- **On-chain Timers**: Contracts can set timers for regular or scheduled
42+
execution, making recurring activities such as subscriptions straightforward to
43+
implement.
2444

25-
The Orchestration API handles asynchronous tasks and complex workflows, including those spanning multiple chains. This empowers smart contracts for actions like inter-chain staking and multi-hop transfers, facilitated by notifications from the transfer vat and IBC middleware updates. Orchestration simplifies complex cross-chain interactions within a secure and user-controlled environment on the Agoric platform.
45+
Agoric's Orchestration APIs simplify controlling accounts on remote chains, moving
46+
assets, and using capabilities on any chain the API reaches.
2647

27-
## Introduction to Orchestration API Flow
48+
## Orchestration API Flow
2849

29-
The following sequence diagram provides a comprehensive overview of the Orchestration process within the Agoric platform. This example illustrates the interaction between various components, highlighting how the Orchestration library (`OrchLib`) facilitates cross-chain operations. This is a good first example to understand the flow of the Orchestration API, showing the steps involved in creating and managing cross-chain transactions.
50+
Orchestration allows us to seamlessly create accounts on remote chains by accessing
51+
their chain objects. We can then use these chain objects to create accounts, get
52+
addresses, and transfer assets between chains. Let's walk through two common
53+
scenarios using the Orchestration API:
3054

31-
<br/>
32-
<img src="/reference/assets/sequence-diagrams/orchestration-workflow-1.svg" width="100%" />
33-
<br/>
55+
### 1. Creating Remote Accounts
56+
57+
The following example shows how to create and interact with an account on the
58+
Stride chain:
59+
60+
```js
61+
// Get Chain objects
62+
const stride = await orch.getChain('stride');
63+
64+
// Create account
65+
const strideAccount = await stride.makeAccount();
66+
67+
// Get address
68+
const strideAddr = strideAccount.getAddress();
69+
```
70+
71+
### 2. Cross-Chain Asset Transfers and Staking
72+
73+
This example demonstrates a complete flow of transferring and staking assets across
74+
multiple chains:
75+
76+
```js
77+
// Transfer funds from Osmosis to Agoric
78+
const osmoToAgoricTransfer = await osmoAccount.transfer(agoricAddr, amount);
79+
80+
// Forward funds from Agoric to Stride
81+
const agoricToStrideTransfer = await agoricAccount.transfer(strideAddr, amount);
82+
83+
// Create liquid stake message for Stride
84+
const liquidStakeMsg = Any.toJSON(
85+
MsgLiquidStake.toProtoMsg({
86+
creator: strideAccount.value,
87+
amount: amount.toString(),
88+
denom: 'uosmo'
89+
})
90+
);
91+
92+
// Execute staking transaction on Stride
93+
await strideAccount.executeEncodedTx([liquidStakeMsg]);
94+
95+
// Transfer staked tokens back to user's Osmosis address
96+
const finalTransfer = await strideAccount.transfer(userOsmoAddress, amount);
97+
```
98+
99+
These examples demonstrate how Orchestration enables seamless cross-chain
100+
operations while abstracting away the underlying complexity. Developers can focus
101+
on building their applications' logic while the Orchestration API handles the
102+
intricate details of cross-chain communication. For more details, check out the code
103+
of [several working examples](https://github.com/Agoric/agoric-sdk/tree/master/packages/orchestration/src/examples), and their [unit tests](https://github.com/Agoric/agoric-sdk/tree/master/packages/orchestration/test/examples). We will walkthrough the code of a couple
104+
of these examples [here](./contract-walkthroughs/).

Diff for: main/guides/orchestration/txvsportfolio.md

+167
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
# Transactional vs. Portfolio Contracts
2+
3+
Agoric Orchestration supports both **transactional contracts** for single interactions and
4+
**portfolio contracts** for rich, persistent user positions. The [send-anywhere contract](./contract-walkthroughs/send-anywhere)
5+
is typical of transactional contracts: each offer is an independent interaction.
6+
[auto-stake-it](https://github.com/Agoric/agoric-sdk/blob/master/packages/orchestration/src/examples/auto-stake-it.contract.js) is typical of portfolio contracts: users have long-lived state.
7+
This section explains their differences and provides examples from real contracts.
8+
9+
| **Characteristic** | **Transactional Contracts** | **Portfolio Contracts** |
10+
| :------------------------ | :---------------------------- | :------------------------------- |
11+
| **Interaction Type** | Single-shot | Multi-step, ongoing |
12+
| **Persistent User State** | No | Yes |
13+
| **User Account** | No dedicated on-chain account | Separate sub-account or position |
14+
| **Example Use Case** | Token swap, cross-chain send | Staking, vaults |
15+
16+
Table: Comparison of Transactional and Portfolio Contracts in Agoric Orchestration
17+
18+
## Transactional Contracts
19+
20+
**Transactional contracts** perform one-shot actions, e.g., swapping tokens or sending them from one
21+
chain to another. Each use is typically triggered by a single transaction, after which there is no
22+
long-lived state managed by the contract for that user.
23+
24+
**Characteristics**:
25+
26+
- **Initiation**: Usually initiated by a single transaction from the user or external source.
27+
- **No per-user account**: The contract does not maintain persistent user-specific state.
28+
- **No smart wallet requirement**: Users often do not require a dedicated on-chain account.
29+
- **One-shot**: The operation typically starts and finishes in a single interaction.
30+
31+
### Example: "Send Anywhere" Contract
32+
33+
The `send-anywhere` contract illustrates how a user can send tokens from Agoric to another chain in
34+
one action. Under the hood, it exposes an `invitation` that, when exercised, moves tokens once and
35+
does not maintain any further user-specific state.
36+
37+
**Key Points**:
38+
39+
- The contract exposes a single `makeSendInvitation` method that returns an Invitation.
40+
- Users deposit tokens into the contract just for this one transaction.
41+
- After the tokens are sent, the seat concludes and there is no ongoing position to manage.
42+
43+
Below is a simplified snippet adapted from the flows (`send-anywhere.flows.js`) showing the essence
44+
of the transactional flow:
45+
46+
```js
47+
export const sendIt = async (
48+
orch,
49+
{ sharedLocalAccountP, log, zoeTools },
50+
seat,
51+
{ chainName, destAddr }
52+
) => {
53+
// 1. Extract the single token amount from the proposal.
54+
const { give } = seat.getProposal();
55+
const { In: amount } = give;
56+
57+
// 2. Transfer the tokens into a local account that can initiate the IBC transfer.
58+
await zoeTools.localTransfer(seat, sharedLocalAccountP, give);
59+
60+
// 3. Execute the cross-chain transfer.
61+
const { chainId } = await orch.getChain(chainName);
62+
await sharedLocalAccountP.transfer(
63+
{ value: destAddr, chainId },
64+
{ denom, value: amount.value }
65+
);
66+
67+
// 4. Finish. No persistent state is stored for this user.
68+
seat.exit();
69+
};
70+
```
71+
72+
In this snippet, we perform the following steps:
73+
74+
1. **Extract token Details**: The user's seat provides the tokens details (_amount_, i.e., _brand_ and _value_) in a single `give`.
75+
2. **Send via localAccount**: An account on the local Agoric chain is used only as a helper to transfer funds from `seat` to an ICA account.
76+
3. **IBC transfer**: Tokens are transferred cross-chain in a single step via [`transfer` API](/guides/orchestration/key-concepts#funds-transfer).
77+
4. **No ongoing portfolio**: Once done, the seat concludes—there is no stored user state.
78+
79+
This is a typical example of a transactional contract. It performs a single
80+
action (sending tokens) and does not maintain any ongoing user state. The user interacts once, and
81+
the contract concludes the operation. This contract is discussed in more detail in the
82+
[`send-anywhere` contract walkthrough](/guides/orchestration/contract-walkthroughs/send-anywhere).
83+
84+
## Portfolio Contracts
85+
86+
**Portfolio contracts** manage long-lived user state and support multiple interactions over time.
87+
They resemble "vaults": you open a portfolio (or vault) position, then manipulate or monitor it as
88+
desired.
89+
90+
**Characteristics**:
91+
92+
- **Persistent per-user state**: Each user typically has their own account.
93+
- **Multiple user actions**: The state can be updated with each new user action.
94+
- **Orchestration Flows**: Users often interact through orchestration flows.
95+
- **Onboarding**: Users first deposit tokens into a personal portfolio for management.
96+
97+
### Example: "Auto Stake It" Contract
98+
99+
The `auto-stake-it` contract demonstrates how to continuously manage a user's positions. A user
100+
"onboards" into the contract by creating accounts on multiple chains (via orchestration) and then
101+
depositing tokens to be staked automatically.
102+
103+
Key points in code:
104+
105+
1. **Make a PortfolioHolder** that stores each user's accounts in a single structure.
106+
2. **Add accounts** to the portfolio. Each user might have multiple chain accounts.
107+
3. **Perform multi-step operations** (e.g. receive tokens over IBC, transfer to staking).
108+
109+
Below is a simplified snippet (`auto-stake-it.flows.js`) showing how a portfolio is set up when a
110+
user calls the "makeAccounts" flow:
111+
112+
```js
113+
export const makeAccounts = async (orch, { makeStakingTap, makePortfolioHolder, chainHub },
114+
seat, { chainName, validator }) => {
115+
seat.exit(); // no funds are exchanged at the moment
116+
117+
// 1. Get chain references (e.g., 'agoric' chain and the remote chain).
118+
const [agoric, remoteChain] = await Promise.all([
119+
orch.getChain('agoric'),
120+
orch.getChain(chainName),
121+
]);
122+
123+
// 2. Create orchestration accounts for each chain.
124+
const [localAccount, stakingAccount] = await Promise.all([
125+
agoric.makeAccount(),
126+
remoteChain.makeAccount(),
127+
]);
128+
129+
// 3. Combine them into a single PortfolioHolder for the user.
130+
const accountEntries = harden([
131+
['agoric', localAccount],
132+
[chainName, stakingAccount],
133+
]);
134+
const publicTopicEntries = /* gather each account's public topics */;
135+
const portfolioHolder = makePortfolioHolder(accountEntries, publicTopicEntries);
136+
137+
// 4. Return a continuing offer result with invitationMakers, etc.
138+
return portfolioHolder.asContinuingOffer();
139+
};
140+
```
141+
142+
In this snippet, we create multiple accounts (one for Agoric, one for the remote chain).
143+
Then, the contract uses `makePortfolioHolder` to maintain these in a persistent store.
144+
Users can perform multiple future actions without losing state. Learn more about the
145+
`makePortfolioHolder` function in the [`makePortfolioHolder` Orchestration API reference](https://agoric-sdk.pages.dev/funcs/_agoric_orchestration.preparePortfolioHolder).
146+
147+
## Choosing Between Transactional and Portfolio
148+
149+
Use **transactional contracts** (like "send-anywhere") when:
150+
151+
- You want a **single-shot interaction** (e.g. a swap, a cross-chain send).
152+
- No ongoing user state is needed.
153+
- The user wants minimal overhead (no dedicated on-chain structure).
154+
155+
Use **portfolio contracts** (like "auto-stake-it") when:
156+
157+
- You need **long-lived, multi-step interactions** (e.g. staking, compounding).
158+
- Each user needs a separate sub-account or position.
159+
- User state must persist (e.g., "my tokens remain staked until I withdraw").
160+
161+
Agoric Orchestration supports both **transactional contracts** for single interactions and
162+
**portfolio contracts** for rich, persistent user positions. Use the pattern that best fits
163+
your user flows. A purely transactional workflow is great for quick, one-time trades, while
164+
a portfolio-based approach is ideal for scenarios like vaults or staking, where users
165+
maintain ongoing positions. Note that rather than a rigid dichotomy, many contracts exist on a
166+
spectrum supporting both interaction types. For instance, the [FastUSDC contract](https://github.com/Agoric/agoric-sdk/tree/master/packages/fast-usdc) supports both
167+
portfolio-style LP positions and transactional trades without persistent user state.

0 commit comments

Comments
 (0)