diff --git a/packages/orchestration/src/examples/unbond.contract.js b/packages/orchestration/src/examples/unbond.contract.js index a303afddf10..e577f2c6fec 100644 --- a/packages/orchestration/src/examples/unbond.contract.js +++ b/packages/orchestration/src/examples/unbond.contract.js @@ -28,13 +28,13 @@ import * as flows from './unbond.flows.js'; * @param {OrchestrationTools} tools */ const contract = async (zcf, privateArgs, zone, { orchestrateAll }) => { - const { unbondAndLiquidStake } = orchestrateAll(flows, { zcf }); + const { unbondAndTransfer } = orchestrateAll(flows, { zcf }); const publicFacet = zone.exo('publicFacet', undefined, { - makeUnbondAndLiquidStakeInvitation() { + makeUnbondAndTransferInvitation() { return zcf.makeInvitation( - unbondAndLiquidStake, - 'Unbond and liquid stake', + unbondAndTransfer, + 'Unbond and transfer', undefined, harden({ // Nothing to give; the funds come from undelegating diff --git a/packages/orchestration/src/examples/unbond.flows.js b/packages/orchestration/src/examples/unbond.flows.js index a203dd088f1..23e89dbff9b 100644 --- a/packages/orchestration/src/examples/unbond.flows.js +++ b/packages/orchestration/src/examples/unbond.flows.js @@ -1,12 +1,10 @@ +import { makeTracer } from '@agoric/internal'; + +const trace = makeTracer('UnbondAndTransfer'); + /** * @import {Orchestrator, OrchestrationFlow} from '../types.js' - * @import {TimerService} from '@agoric/time'; - * @import {LocalChain} from '@agoric/vats/src/localchain.js'; - * @import {NameHub} from '@agoric/vats'; - * @import {Remote} from '@agoric/internal'; - * @import {Zone} from '@agoric/zone'; - * @import {CosmosInterchainService} from '../exos/exo-interfaces.js'; - * @import {OrchestrationTools} from '../utils/start-helper.js'; + * @import {DelegationResponse} from '@agoric/cosmic-proto/cosmos/staking/v1beta1/staking.js'; */ /** @@ -14,25 +12,31 @@ * @param {Orchestrator} orch * @param {object} ctx * @param {ZCF} ctx.zcf - * @param {ZCFSeat} _seat - * @param {undefined} _offerArgs */ -export const unbondAndLiquidStake = async ( - orch, - { zcf }, - _seat, - _offerArgs, -) => { +export const unbondAndTransfer = async (orch, { zcf }) => { console.log('zcf within the membrane', zcf); // Osmosis is one of the few chains with icqEnabled const osmosis = await orch.getChain('osmosis'); // In a real world scenario, accounts would be re-used across invokations of the handler const osmoAccount = await osmosis.makeAccount(); - // TODO https://github.com/Agoric/agoric-sdk/issues/10016 - // const delegations = await celestiaAccount.getDelegations(); - // // wait for the undelegations to be complete (may take weeks) - // await celestiaAccount.undelegate(delegations); + /** @type {DelegationResponse[]} */ + const delegations = await osmoAccount.getDelegations(); + trace('delegations', delegations); + // wait for the undelegations to be complete (may take weeks) + await osmoAccount.undelegate( + delegations.map(d => ({ + validator: { + chainId: 'osmosis-1', + value: /** @type {`${string}valoper${string}`} */ ( + d.delegation.validatorAddress + ), + encoding: 'bech32', + }, + amount: { denom: 'uosmo', value: BigInt(d.balance.amount) }, + })), + ); + // ??? should this be synchronous? depends on how names are resolved. const stride = await orch.getChain('stride'); const strideAccount = await stride.makeAccount(); @@ -44,4 +48,4 @@ export const unbondAndLiquidStake = async ( // await strideAccount.liquidStake(tiaAmt); console.log(osmoAccount, strideAccount); }; -harden(unbondAndLiquidStake); +harden(unbondAndTransfer); diff --git a/packages/orchestration/test/examples/snapshots/unbond.contract.test.ts.md b/packages/orchestration/test/examples/snapshots/unbond.contract.test.ts.md index dc4bf4aa5a3..82a7b2f488e 100644 --- a/packages/orchestration/test/examples/snapshots/unbond.contract.test.ts.md +++ b/packages/orchestration/test/examples/snapshots/unbond.contract.test.ts.md @@ -26,7 +26,7 @@ Generated by [AVA](https://avajs.dev). }, contract: { orchestration: { - unbondAndLiquidStake: { + unbondAndTransfer: { asyncFlow_kindHandle: 'Alleged: kind', }, }, diff --git a/packages/orchestration/test/examples/snapshots/unbond.contract.test.ts.snap b/packages/orchestration/test/examples/snapshots/unbond.contract.test.ts.snap index 26978e4b049..90478398c1d 100644 Binary files a/packages/orchestration/test/examples/snapshots/unbond.contract.test.ts.snap and b/packages/orchestration/test/examples/snapshots/unbond.contract.test.ts.snap differ diff --git a/packages/orchestration/test/examples/unbond.contract.test.ts b/packages/orchestration/test/examples/unbond.contract.test.ts index 74266f0b62c..ae9d74d8f91 100644 --- a/packages/orchestration/test/examples/unbond.contract.test.ts +++ b/packages/orchestration/test/examples/unbond.contract.test.ts @@ -4,7 +4,13 @@ import { setUpZoeForTest } from '@agoric/zoe/tools/setup-zoe.js'; import { E } from '@endo/far'; import path from 'path'; import { inspectMapStore } from '@agoric/internal/src/testing-utils.js'; +import { QueryDelegatorDelegationsResponse } from '@agoric/cosmic-proto/cosmos/staking/v1beta1/query.js'; +import { MsgUndelegateResponse } from '@agoric/cosmic-proto/cosmos/staking/v1beta1/tx.js'; import { commonSetup } from '../supports.js'; +import { + buildMsgResponseString, + buildQueryResponseString, +} from '../../tools/ibc-mocks.js'; const dirname = path.dirname(new URL(import.meta.url).pathname); @@ -14,11 +20,42 @@ type StartFn = test('start', async t => { const { - bootstrap: { vowTools: vt }, + bootstrap: { timer, vowTools: vt }, brands: { ist }, commonPrivateArgs, + mocks: { ibcBridge }, } = await commonSetup(t); + const buildMocks = () => { + const makeDelegationsResponse = () => + buildQueryResponseString(QueryDelegatorDelegationsResponse, { + delegationResponses: [ + { + delegation: { + delegatorAddress: 'cosmos1test', + validatorAddress: 'cosmosvaloper1xyz', + shares: '1000000', + }, + balance: { denom: 'uatom', amount: '1000000' }, + }, + ], + pagination: { nextKey: new Uint8Array(), total: 1n }, + }); + const makeUndelegateResponse = () => + buildMsgResponseString(MsgUndelegateResponse, { + completionTime: { seconds: 3600n, nanos: 0 }, + }); + + return { + 'eyJkYXRhIjoiQ2tNS0RRb0xZMjl6Ylc5ek1YUmxjM1FTTWk5amIzTnRiM011YzNSaGEybHVaeTUyTVdKbGRHRXhMbEYxWlhKNUwwUmxiR1ZuWVhSdmNrUmxiR1ZuWVhScGIyNXoiLCJtZW1vIjoiIn0=': + makeDelegationsResponse(), + 'eyJ0eXBlIjoxLCJkYXRhIjoiQ2xzS0pTOWpiM050YjNNdWMzUmhhMmx1Wnk1Mk1XSmxkR0V4TGsxeloxVnVaR1ZzWldkaGRHVVNNZ29MWTI5emJXOXpNWFJsYzNRU0VXTnZjMjF2YzNaaGJHOXdaWEl4ZUhsNkdoQUtCWFZ2YzIxdkVnY3hNREF3TURBdyIsIm1lbW8iOiIifQ==': + makeUndelegateResponse(), + }; + }; + + ibcBridge.setMockAck(buildMocks()); + let contractBaggage; const { zoe, bundleAndInstall } = await setUpZoeForTest({ setJig: ({ baggage }) => { @@ -35,11 +72,11 @@ test('start', async t => { commonPrivateArgs, ); - const inv = E(publicFacet).makeUnbondAndLiquidStakeInvitation(); + const inv = E(publicFacet).makeUnbondAndTransferInvitation(); t.is( (await E(zoe).getInvitationDetails(inv)).description, - 'Unbond and liquid stake', + 'Unbond and transfer', ); const userSeat = await E(zoe).offer( @@ -48,7 +85,13 @@ test('start', async t => { {}, { validator: 'agoric1valopsfufu' }, ); - const result = await vt.when(E(userSeat).getOfferResult()); + const resultP = vt.when(E(userSeat).getOfferResult()); + t.truthy(resultP); + + // Wait for the completionTime to pass + timer.advanceBy(3600n * 1000n); + + const result = await resultP; t.is(result, undefined); const tree = inspectMapStore(contractBaggage);