Cross-Chain Unbond Contract
This walkthrough outlines the functionality of the Unbond Contract that enables unbonding of assets from a Cosmos-based chain and transferring them to another chain using IBC (Inter-Blockchain Communication).
Overview
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.
The contract consists of two main parts:
- Contract File (
unbond.contract.js
): Defines the contract structure, and public-facing APIs. - Flows File (
unbond.flows.js
): Implements the logic for the unbonding and transfer operations.
Contract: unbond.contract.js
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.
Imports
The key imports include the withOrchestration
helper, pattern matching utility M
, and the flows from unbond.flows.js
files.
import { M } from '@endo/patterns';
import { withOrchestration } from '../utils/start-helper.js';
import * as flows from './unbond.flows.js';
contract
Function
The contract
function when wrapped inside withOrchestration
defines the start
function which is the entry point of the contract. The contract exports a start
function below. 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:
zcf
: Zoe Contract Facet.privateArgs
: Object containing remote references to various services.zone
: AZone
object with access to storage for persistent data.OrchestrationTools
: A set of Orchestration related tools needed by the contract.
const contract = async (
zcf,
privateArgs,
zone,
{ orchestrateAll, zcfTools }
) => {
const { unbondAndTransfer } = orchestrateAll(flows, { zcfTools });
const publicFacet = zone.exo('publicFacet', undefined, {
makeUnbondAndTransferInvitation() {
return zcf.makeInvitation(
unbondAndTransfer,
'Unbond and transfer',
undefined,
harden({
give: {},
want: {},
exit: M.any()
})
);
}
});
return harden({ publicFacet });
};
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.
start
function
The following code defines the start
function of the contract that is returned by a call to withOrchestration
with contract
function as a parameter. In essence contract
function is the entry point or start
function of this contract with some Orchestration setup.
export const start = withOrchestration(contract);
Flows: unbond.flows.js
This file contains the Orchestration flow that performs the unbonding and transferring of assets across chains.
Flow Function: unbondAndTransfer
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).
export const unbondAndTransfer = async (orch, { zcfTools }) => {
const osmosis = await orch.getChain('osmosis');
const osmoDenom = (await osmosis.getChainInfo()).stakingTokens[0].denom;
const osmoAccount = await osmosis.makeAccount();
const delegations = await osmoAccount.getDelegations();
const osmoDelegations = delegations.filter(d => d.amount.denom === osmoDenom);
await osmoAccount.undelegate(osmoDelegations);
const stride = await orch.getChain('stride');
const strideAccount = await stride.makeAccount();
const balance = await osmoAccount.getBalance(osmoDenom);
await osmoAccount.transfer(strideAccount.getAddress(), balance);
};
The above code achieve several things including:
- Retrieval of
osmosis
chain object, andosmo
denom from the chain info. - Create an
osmoAccount
onosmosis
. Note that in real-life scenario, this step would not be needed as we would be using an account that has already delegated someosmo
assets. - Perform
undelegate
onosmo
delegations of theosmoAccount
. - Create an account on
stride
chain. - Transfer all
osmo
balance fromosmoAccount
tostrideAccount
.
Upon successful transfer, the assets are moved from the Osmosis chain to the Stride chain, ready for the user to claim.