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: AZoneobject 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
osmosischain object, andosmodenom from the chain info. - Create an
osmoAccountonosmosis. Note that in real-life scenario, this step would not be needed as we would be using an account that has already delegated someosmoassets. - Perform
undelegateonosmodelegations of theosmoAccount. - Create an account on
stridechain. - Transfer all
osmobalance fromosmoAccounttostrideAccount.
Upon successful transfer, the assets are moved from the Osmosis chain to the Stride chain, ready for the user to claim.