Skip to content

Commit adac99a

Browse files
authored
Merge pull request #1221 from Agoric/ms/update-unbond-walkthrough
Update Orch/Unbond Walkthrough
2 parents 8a781e5 + 1a2fc75 commit adac99a

File tree

1 file changed

+76
-121
lines changed

1 file changed

+76
-121
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,163 +1,118 @@
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-
9-
## Imports
10-
11-
```js
12-
import { M } from '@endo/patterns';
13-
import { withOrchestration } from '../utils/start-helper.js';
14-
```
8+
<br/> -->
159

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.
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).
1812

19-
## JSDoc Annotations for Type Information
13+
## Overview
2014

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-
```
15+
The Unbond Contract leverages the Agoric Orchestration API to interact with external chains, like Osmosis and Stride, to facilitate unbonding and transferring assets from one chain to another.
3416

35-
This includes type information annotations to help with TypeScript or JSDoc, making it easier to understand the types used throughout the contract.
17+
The contract consists of two main parts:
3618

37-
## `unbondAndLiquidStakeFn` Function
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.
3821

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-
```
22+
## Contract: `unbond.contract.js`
5023

51-
### Function Parameters
24+
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.
5225

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).
26+
### Imports
5727

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

6030
```js
61-
const omni = await orch.getChain('omniflixhub');
62-
const omniAccount = await omni.makeAccount();
31+
import { M } from '@endo/patterns';
32+
import { withOrchestration } from '../utils/start-helper.js';
33+
import * as flows from './unbond.flows.js';
6334
```
6435

65-
### Get Chain
66-
67-
Retrieves the omniflixhub chain object using the orchestrator.
36+
### `contract` Function
6837

69-
### Make Account
38+
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:
7039

71-
Creates an account on the omniflixhub chain.
72-
73-
## Interaction with Stride Chain
40+
- `zcf`: Zoe Contract Facet.
41+
- `privateArgs`: Object containing remote references to various services.
42+
- `zone`: A `Zone` object with access to storage for persistent data.
43+
- `OrchestrationTools`: A set of Orchestration related tools needed by the contract.
7444

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

80-
### Get Chain
81-
82-
Retrieves the stride chain object using the orchestrator.
83-
84-
### Make Account
73+
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.
8574

86-
Creates an account on the stride chain.
75+
### `start` function
8776

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+
## Flows: `unbond.flows.js`
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+
This file contains the Orchestration flow that performs the unbonding and transferring of assets across chains.
86+
87+
### Flow Function: `unbondAndTransfer`
11788

118-
## Offer Handler for Unbond and Liquid Stake
89+
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).
11990

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

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

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

133-
## Make Invitation and Create `publicFacet`
102+
const stride = await orch.getChain('stride');
103+
const strideAccount = await stride.makeAccount();
134104

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 });
105+
const balance = await osmoAccount.getBalance(osmoDenom);
106+
await osmoAccount.transfer(strideAccount.getAddress(), balance);
107+
};
153108
```
154109

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).
110+
The above code achieve several things including:
156111

157-
## `start` Function
158-
159-
```js
160-
export const start = withOrchestration(contract);
161-
```
112+
- Retrieval of `osmosis` chain object, and `osmo` denom from the chain info.
113+
- 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_.
114+
- Perform `undelegate` on `osmo` delegations of the `osmoAccount`.
115+
- Create an account on `stride` chain.
116+
- Transfer all `osmo` balance from `osmoAccount` to `strideAccount`.
162117

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.
118+
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)