Skip to content

Commit aebbc20

Browse files
committed
docs: update unbond walkthrough
1 parent 8cbab6c commit aebbc20

File tree

1 file changed

+78
-121
lines changed

1 file changed

+78
-121
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,163 +1,120 @@
11
# Cross-Chain Unbond Contract
22

3-
## Overview Diagram
3+
<!-- XXX the diagram below is a useful part of the page but it needs to be updated before it is uncommented. -->
4+
<!-- ## Overview Diagram
45
56
<br/>
67
<img src="/reference/assets/sequence-diagrams/orchestration-unbond-example.svg" width="100%" />
7-
<br/>
8+
<br/> -->
89

9-
## Imports
10+
This walkthrough outlines the functionality of the Unbond Contract that enables unbonding of assets from a
11+
Cosmos-based chain and transferring them to another chain using IBC (Inter-Blockchain Communication).
1012

11-
```js
12-
import { M } from '@endo/patterns';
13-
import { withOrchestration } from '../utils/start-helper.js';
14-
```
13+
## Overview
1514

16-
- `M`: Imported from @endo/patterns, provides pattern-matching utilities.
17-
- `withOrchestration`: Imported from a utility module, used to set up and provide access to orchestration tools.
15+
The Unbond Contract leverages the Agoric orchestration to interact with external chains, like Osmosis and Stride, to facilitate unbonding and transferring assets from one chain to another.
1816

19-
## JSDoc Annotations for Type Information
17+
The contract consists of two main parts:
2018

21-
```js
22-
/**
23-
* @import {Orchestrator, IcaAccount, CosmosValidatorAddress} from '../types.js'
24-
* @import {TimerService} from '@agoric/time';
25-
* @import {Baggage} from '@agoric/vat-data';
26-
* @import {LocalChain} from '@agoric/vats/src/localchain.js';
27-
* @import {NameHub} from '@agoric/vats';
28-
* @import {Remote} from '@agoric/internal';
29-
* @import {Zone} from '@agoric/zone';
30-
* @import {CosmosInterchainService} from '../exos/cosmos-interchain-service.js';
31-
* @import {OrchestrationTools} from '../utils/start-helper.js';
32-
*/
33-
```
19+
- **Contract File (`unbond.contract.js`)**: Defines the contract structure, and public-facing APIs.
20+
- **Flows File (`unbond.flows.js`)**: Implements the logic for the unbonding and transfer operations.
3421

35-
This includes type information annotations to help with TypeScript or JSDoc, making it easier to understand the types used throughout the contract.
22+
---
3623

37-
## `unbondAndLiquidStakeFn` Function
38-
39-
```js
40-
/**
41-
* @param {Orchestrator} orch
42-
* @param {object} ctx
43-
* @param {ZCF} ctx.zcf
44-
* @param {ZCFSeat} _seat
45-
* @param {undefined} _offerArgs
46-
*/
47-
const unbondAndLiquidStakeFn = async (orch, { zcf }, _seat, _offerArgs) => {
48-
// ...
49-
```
24+
## Contract: `unbond.contract.js`
5025

51-
### Function Parameters
26+
This file contains the main orchestration contract, which is wrapped using the `withOrchestration` helper for Zoe. It exposes a public facet that allows users to initiate the unbonding process and transfer assets to another chain.
5227

53-
- `orch`: The orchestrator object to manage interactions with chains/accounts.
54-
- `ctx`: Context object containing zcf.
55-
- `_seat`: The seat representing the user’s position in the contract (not used in this function, hence `_` prefix).
56-
- `_offerArgs`: Arguments provided with the offer (not used in this function, hence `_` prefix).
28+
### Imports
5729

58-
## Interacting with Chains
30+
The key imports include the `withOrchestration` helper, pattern matching utility `M`, and the flows from `unbond.flows.js` files.
5931

6032
```js
61-
const omni = await orch.getChain('omniflixhub');
62-
const omniAccount = await omni.makeAccount();
33+
import { M } from '@endo/patterns';
34+
import { withOrchestration } from '../utils/start-helper.js';
35+
import * as flows from './unbond.flows.js';
6336
```
6437

65-
### Get Chain
66-
67-
Retrieves the omniflixhub chain object using the orchestrator.
68-
69-
### Make Account
38+
### `contract` Function
7039

71-
Creates an account on the omniflixhub chain.
40+
The `contract` function when wrapped inside `withOrchestration` defines the [`start` function](#start-function) which is the entry point of the contract. The contract exports a `start` function [below](#start-function). It is merely a convention/convenience that we define a more abstract `contract` function here and pass it to `withOrchestration`. The `contract` function parameters include:
7241

73-
## Interaction with Stride Chain
42+
- `zcf`: Zoe Contract Facet.
43+
- `privateArgs`: Object containing remote references to various services.
44+
- `zone`: A `Zone` object with access to storage for persistent data.
45+
- `OrchestrationTools`: A set of orchestration related tools needed by the contract.
7446

7547
```js
76-
const stride = await orch.getChain('stride');
77-
const strideAccount = await stride.makeAccount();
48+
const contract = async (
49+
zcf,
50+
privateArgs,
51+
zone,
52+
{ orchestrateAll, zcfTools }
53+
) => {
54+
const { unbondAndTransfer } = orchestrateAll(flows, { zcfTools });
55+
56+
const publicFacet = zone.exo('publicFacet', undefined, {
57+
makeUnbondAndTransferInvitation() {
58+
return zcf.makeInvitation(
59+
unbondAndTransfer,
60+
'Unbond and transfer',
61+
undefined,
62+
harden({
63+
give: {},
64+
want: {},
65+
exit: M.any()
66+
})
67+
);
68+
}
69+
});
70+
71+
return harden({ publicFacet });
72+
};
7873
```
7974

80-
### Get Chain
75+
The `orchestrateAll` function links the flows from the flows file to the contract logic. In this case, it links the `unbondAndTransfer` flow. The `publicFacet` exposes the `makeUnbondAndTransferInvitation` method, which creates a Zoe invitation to allow users to make an offer for the unbonding and transferring process.
8176

82-
Retrieves the stride chain object using the orchestrator.
83-
84-
### Make Account
85-
86-
Creates an account on the stride chain.
87-
88-
## `contract` Function
89-
90-
The `contract` function when wrapped inside `withOrchestration` defines the [`start` function](#start-function) which is the entry point of the contract. The contract exports a `start` function [below](#start-function). It is merely a convention/convenience that we define a more abstract `contract` function here and pass it to `withOrchestration`. The arguments of this function are `zcf`, `privateAge`, `zone`, and `tools` for orchestration.
77+
The following code defines the `start` function of the contract that is returned by a call to `withOrchestration` with [`contract` function](#contract-function) as a parameter. In essence `contract` function is the entry point or `start` function of this contract with some orchestration setup.
9178

9279
```js
93-
/**
94-
* Orchestration contract to be wrapped by withOrchestration for Zoe
95-
*
96-
* @param {ZCF} zcf
97-
* @param {{
98-
* agoricNames: Remote<NameHub>;
99-
* localchain: Remote<LocalChain>;
100-
* orchestrationService: Remote<CosmosInterchainService>;
101-
* storageNode: Remote<StorageNode>;
102-
* marshaller: Marshaller;
103-
* timerService: Remote<TimerService>;
104-
* }} privateArgs
105-
* @param {Zone} zone
106-
* @param {OrchestrationTools} tools
107-
*/
108-
const contract = async (zcf, privateArgs, zone, { orchestrate }) => {
80+
export const start = withOrchestration(contract);
10981
```
11082

111-
### `contract` Function Parameters:
83+
---
11284

113-
- `zcf`: Zoe Contract Facet.
114-
- `privateArgs`: Object containing remote references to various services.
115-
- `zone`: A `Zone` object with access to storage for persistent data.
116-
- `OrchestrationTools`: A set of orchestration related tools needed by the contract.
85+
## Flows: `unbond.flows.js`
11786

118-
## Offer Handler for Unbond and Liquid Stake
87+
This file contains the orchestration flow that performs the unbonding and transferring of assets across chains.
88+
89+
### Flow Function: `unbondAndTransfer`
90+
91+
The `unbondAndTransfer` flow orchestrates the process of unbonding assets from a source chain (e.g., Osmosis) and transferring them to a destination chain (e.g., Stride).
11992

12093
```js
121-
/** @type {OfferHandler} */
122-
const unbondAndLiquidStake = orchestrate(
123-
'LSTTia',
124-
{ zcf },
125-
unbondAndLiquidStakeFn
126-
);
127-
```
94+
export const unbondAndTransfer = async (orch, { zcfTools }) => {
95+
const osmosis = await orch.getChain('osmosis');
96+
const osmoDenom = (await osmosis.getChainInfo()).stakingTokens[0].denom;
12897

129-
### Offer Handler
98+
const osmoAccount = await osmosis.makeAccount();
99+
const delegations = await osmoAccount.getDelegations();
100+
const osmoDelegations = delegations.filter(d => d.amount.denom === osmoDenom);
130101

131-
Defines the offer handler for the unbond and liquid stake operation using [`unbondAndLiquidStakeFn`](#unbondandliquidstakefn-function).
102+
await osmoAccount.undelegate(osmoDelegations);
132103

133-
## Make Invitation and Create `publicFacet`
104+
const stride = await orch.getChain('stride');
105+
const strideAccount = await stride.makeAccount();
134106

135-
```js
136-
const publicFacet = zone.exo('publicFacet', undefined, {
137-
makeUnbondAndLiquidStakeInvitation() {
138-
return zcf.makeInvitation(
139-
unbondAndLiquidStake,
140-
'Unbond and liquid stake',
141-
undefined,
142-
harden({
143-
// Nothing to give; the funds come from undelegating
144-
give: {},
145-
want: {}, // XXX ChainAccount Ownable?
146-
exit: M.any()
147-
})
148-
);
149-
}
150-
});
151-
152-
return harden({ publicFacet });
107+
const balance = await osmoAccount.getBalance(osmoDenom);
108+
await osmoAccount.transfer(strideAccount.getAddress(), balance);
109+
};
153110
```
154111

155-
Defines the `publicFacet` for the contract, which includes the method to make an `invitation`, and returns the hardened public facet. Defining `publicFacet` with `zone.exo` makes it [remotely accessible](/glossary/#exo) and persistent through contract upgrades with a [durable `zone`](/glossary/#zone).
112+
The above code achieve several things including:
156113

157-
## `start` Function
158-
159-
```js
160-
export const start = withOrchestration(contract);
161-
```
114+
- Retrieval of `osmosis` chain object, and `osmo` denom from the chain info.
115+
- Create an `osmoAccount` on `osmosis`. _Note that in real-life scenario, this step would not be needed as we would be using an account that has already delegated some `osmo` assets_.
116+
- Perform `undelegate` on `osmo` delegations of the `osmoAccount`.
117+
- Create an account on `stride` chain.
118+
- Transfer all `osmo` balance from `osmoAccount` to `strideAccount`.
162119

163-
Defines the `start` function of the contract that is returned by a call to `withOrchestration` with [`contract` function](#contract-function) as a parameter. In essence `contract` function is the entry point or `start` function of this contract with some orchestration setup.
120+
Upon successful transfer, the assets are moved from the Osmosis chain to the Stride chain, ready for the user to claim.

0 commit comments

Comments
 (0)