Skip to content

Commit b44a9aa

Browse files
committed
docs: orca contract walkthrough
1 parent 6bb1f95 commit b44a9aa

File tree

2 files changed

+188
-15
lines changed

2 files changed

+188
-15
lines changed

main/guides/orchestration/contract-walkthroughs.md

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@
22

33
This section is designed to provide detailed explanations and insights into example orchestration smart contracts.
44

5-
In this section, we will cover three primary contracts:
5+
In this section, we will cover two primary contracts:
66

77
1. **Assets Transfer Contract**: A guide to `send-anywhere` contract that demonstrates a simple yet robust and secure way for cross-chain assets transfer.
8-
2. **Swap Contract**: A comprehensive guide to the process of swapping assets between different chains using the Agoric orchestration library.
9-
3. **Unbond Contract**: A detailed walkthrough of the unbonding and liquid staking process, highlighting the steps involved in managing cross-chain operations.
8+
2. **Unbond Contract**: A detailed walkthrough of the unbonding and liquid staking process, highlighting the steps involved in managing cross-chain operations.
109

1110
Each walkthrough will include detailed explanations of the contract code, providing insights into the mechanics and best practices of smart contract development on the Agoric platform. By the end of these walkthroughs, you should have a solid understanding of how to utilize Agoric’s tools and libraries to create robust and efficient cross-chain smart contracts.
1211

@@ -21,17 +20,6 @@ The "Send Anywhere" contract is a robust and secure solution for transferring as
2120

2221
[See Contract Overview](/guides/orchestration/getting-started/contract-walkthrough/send-anywhere)
2322

24-
## Swap Contract
25-
26-
The Swap Contract demonstrates how to swap assets between the Agoric chain and another blockchain. This example covers:
27-
28-
- Initializing and setting up the contract.
29-
- Creating and managing accounts on different chains.
30-
- Executing cross-chain asset transfers.
31-
- Handling errors and ensuring secure transactions.
32-
33-
[See Contract Overview](/guides/orchestration/getting-started/contract-walkthrough/cross-chain-swap)
34-
3523
## Unbond Contract
3624

3725
The Unbond Contract focuses on the process of unbonding staked assets and performing liquid staking. Key topics include:

main/guides/orchestration/orchestration-basics.md

Lines changed: 186 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,189 @@
22

33
To get started with developing using the Orchestration API, developers can make use of our [dapp-orchestration-basics](https://github.com/Agoric/dapp-orchestration-basics) template.
44

5-
Following the dApp pattern of our existing dapp templates, `dapp-orchestration-basics` contains both ui & contract folders within a single yarn workspace.
5+
Following the dApp pattern of our existing dapp templates, `dapp-orchestration-basics` contains both ui & contract directory within a single yarn workspace.
6+
7+
## Installation and Deployment
8+
9+
The dApp implements a smart contract that can installed and deployed any Agoric testnet. Since, the contract interacts with remote chains, we need to a multichain environment - see [Agoric Multichain-Testing]() for details. Follow in the instructions in [dApp Readme]() to install, deploy and interact with dApp on your local machine.
10+
11+
## Orca Contract Code Walkthrough
12+
13+
This section provides a walkthrough of the Orca contract code, explaining its structure, key components, and functionality. The Orca contract is designed to manage orchestration accounts and fund them. It interacts with multiple chains and provides functionality for creating accounts and funding them. The code for the contract logic is in two files:
14+
15+
1. `orca.contract.js`
16+
2. `orca.flows.js`
17+
18+
### Walkthrough: `orca.contract.js`
19+
20+
The `orca.contract.js` files brings in necessary dependencies and types from various Agoric packages. The flows import contains specific logic for the Orca contract operations.
21+
22+
```js
23+
import { AmountShape } from '@agoric/ertp';
24+
import { makeTracer } from '@agoric/internal';
25+
import { withOrchestration } from '@agoric/orchestration/src/utils/start-helper.js';
26+
import { ChainInfoShape } from '@agoric/orchestration/src/typeGuards.js';
27+
import { InvitationShape } from '@agoric/zoe/src/typeGuards.js';
28+
import { M } from '@endo/patterns';
29+
import * as flows from './orca.flows.js';
30+
```
31+
32+
#### Type Definitions and Shapes
33+
34+
These definitions create shapes for validating the structure of amounts and orchestration powers.
35+
36+
```js
37+
const SingleAmountRecord = M.and(
38+
M.recordOf(M.string(), AmountShape, { numPropertiesLimit: 1 }),
39+
M.not(harden({}))
40+
);
41+
42+
const OrchestrationPowersShape = M.splitRecord({
43+
localchain: M.remotable('localchain'),
44+
orchestrationService: M.remotable('orchestrationService'),
45+
storageNode: M.remotable('storageNode'),
46+
timerService: M.remotable('timerService'),
47+
agoricNames: M.remotable('agoricNames')
48+
});
49+
```
50+
51+
#### Main Contract Function
52+
53+
This is the main contract function that sets up the contract's functionality.
54+
55+
```js
56+
const contract = async (
57+
zcf,
58+
privateArgs,
59+
zone,
60+
{ orchestrateAll, zoeTools, chainHub }
61+
) => {
62+
// ... (contract logic)
63+
};
64+
```
65+
66+
Within the `contract` function, following actions are performed.
67+
68+
- **Chain Registration**: Below section registers chains and their connections with the `chainHub`.
69+
70+
```js
71+
const { chainDetails } = zcf.getTerms();
72+
for (const [name, info] of entries(chainDetails)) {
73+
const { connections = {} } = info;
74+
trace('register', name, {
75+
chainId: info.chainId,
76+
connections: keys(connections)
77+
});
78+
chainHub.registerChain(name, info);
79+
for (const [chainId, connInfo] of entries(connections)) {
80+
chainHub.registerConnection(info.chainId, chainId, connInfo);
81+
}
82+
}
83+
```
84+
85+
- **Creating Account and Funding Functions**: These functions are created using the `orchestrateAll` helper, which sets up the necessary flow logic for account creation and funding.
86+
87+
```js
88+
const { makeAccount, makeCreateAndFund } = orchestrateAll(flows, {
89+
localTransfer: zoeTools.localTransfer
90+
});
91+
```
92+
93+
- **Public Facet**: The public facet provides two methods: `makeAccountInvitation` creates an invitation to make an orchestration account, and `makeCreateAndFundInvitation` creates an invitation to make an account and fund it.
94+
95+
```js
96+
const publicFacet = zone.exo(
97+
'Orca Public Facet',
98+
M.interface('Orca PF', {
99+
makeAccountInvitation: M.callWhen().returns(InvitationShape),
100+
makeCreateAndFundInvitation: M.callWhen().returns(InvitationShape)
101+
}),
102+
{
103+
makeAccountInvitation() {
104+
return zcf.makeInvitation(makeAccount, 'Make an Orchestration Account');
105+
},
106+
makeCreateAndFundInvitation() {
107+
return zcf.makeInvitation(
108+
makeCreateAndFund,
109+
'Make an Orchestration Account and Fund it',
110+
undefined,
111+
M.splitRecord({ give: SingleAmountRecord })
112+
);
113+
}
114+
}
115+
);
116+
```
117+
118+
#### `start` Function
119+
120+
The start function is wrapped with `withOrchestration`, which provides additional orchestration setup and tools for the contract.
121+
122+
```js
123+
export const start = withOrchestration(contract);
124+
harden(start);
125+
```
126+
127+
### Walkthrough `orca.flows.js`
128+
129+
This section provides a walkthrough of the `orca.flows.js` file, which contains flow functions for the Orca contract. The `orca.flows.js` file defines two main functions:
130+
131+
1. `makeAccount`: Creates an account on a Cosmos chain.
132+
2. `makeCreateAndFund`: Creates an account on a Cosmos chain and funds it.
133+
134+
These functions are called by the Zoe vat when a user makes an offer using a corresponding orca contract inivitation.
135+
136+
#### `makeAccount` Function
137+
138+
This function creates an account on a specified Cosmos chain. Here are the parameters of this function:
139+
140+
- `orch`: An Orchestrator instance
141+
- `_ctx`: Unused context object
142+
- `seat`: A `ZCFSeat` instance
143+
- `offerArgs`: An object containing `chainName` and `denom`
144+
145+
The function validates the `offerArgs` to ensure it contains a `chainName`, retrieves the specified chain using `orch`, creates an account on the chain using `chain.makeAccount()`, and returns the account as a continuing offer. Below is the code of `makeAccount` after removing some debug information logging code.
146+
147+
```js
148+
mustMatch(offerArgs, M.splitRecord({ chainName: M.string() }));
149+
const { chainName } = offerArgs;
150+
seat.exit();
151+
const chain = await orch.getChain(chainName);
152+
const chainAccount = await chain.makeAccount();
153+
return chainAccount.asContinuingOffer();
154+
```
155+
156+
#### `makeCreateAndFund` Function
157+
158+
This function creates an account on a specified Cosmos chain and funds it. It accepts the same set of parameters as `make Account`. The function:
159+
160+
- Extracts the amount to be transferred from the seat's proposal, and retrieves both the Agoric chain and the specified target chain.
161+
- Fetches chain info and asset information.
162+
- Creates accounts on both the Agoric chain (local) and the target chain (remote).
163+
- Transfers funds from the seat to the local account.
164+
- Transfers half of the received funds from the local account to the remote account.
165+
- Checks the balance of the remote account, and returns the remote account as a continuing offer.
166+
167+
Below is the code of `makeCreateAndFund` after removing some debug information logging code.
168+
169+
```js
170+
const { give } = seat.getProposal();
171+
const [[_kw, amt]] = Object.entries(give);
172+
const [agoric, chain] = await Promise.all([
173+
orch.getChain('agoric'),
174+
orch.getChain(chainName),
175+
]);
176+
const localAccount = await agoric.makeAccount();
177+
const remoteAccount = await chain.makeAccount();
178+
const remoteAddress = await remoteAccount.getAddress();
179+
await localTransfer(seat, localAccount, give);
180+
await localAccount.transfer(
181+
{
182+
denom: 'ubld',
183+
value: amt.value / 2n,
184+
},
185+
remoteAddress,
186+
);
187+
seat.exit();
188+
return remoteAccount.asContinuingOffer();
189+
};
190+
```

0 commit comments

Comments
 (0)