Skip to content

Commit

Permalink
types: update OrchestrationAccount type
Browse files Browse the repository at this point in the history
- fixes `CosmosChainAccountMethods` that depended on non-existent `icaEnabled` parameter
- only expose `IcaAccount` methods available on `OrchestrationAccount<CosmosChainInfo>`
- removes `IcaAccount` and `StakingAccountQueries` methods from `OrchestrationAccount<agoric>`
- improve `monitorTransfers` doc string
  • Loading branch information
0xpatrickdev committed Nov 13, 2024
1 parent e67e86b commit 3262f6c
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 39 deletions.
66 changes: 40 additions & 26 deletions packages/orchestration/src/cosmos-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type {
} from '@agoric/cosmic-proto/cosmos/staking/v1beta1/staking.js';
import type { TxBody } from '@agoric/cosmic-proto/cosmos/tx/v1beta1/tx.js';
import type { MsgTransfer } from '@agoric/cosmic-proto/ibc/applications/transfer/v1/tx.js';
import type { FungibleTokenPacketData } from '@agoric/cosmic-proto/ibc/applications/transfer/v2/packet.js';
import type {
State as IBCChannelState,
Order,
Expand All @@ -19,7 +20,11 @@ import type {
} from '@agoric/cosmic-proto/tendermint/abci/types.js';
import type { Brand, Purse, Payment, Amount } from '@agoric/ertp/src/types.js';
import type { Port } from '@agoric/network';
import type { IBCChannelID, IBCConnectionID } from '@agoric/vats';
import type {
IBCChannelID,
IBCConnectionID,
VTransferIBCEvent,
} from '@agoric/vats';
import type {
TargetApp,
TargetRegistration,
Expand Down Expand Up @@ -226,20 +231,10 @@ export interface StakingAccountActions {
}

/**
* Low level object that supports queries and operations for an account on a remote chain.
* Low level methods from IcaAccount that we pass through to CosmosOrchestrationAccount
*/
export interface IcaAccount {
/**
* @returns the address of the account on the remote chain
*/
getAddress: () => ChainAddress;

/**
* Submit a transaction on behalf of the remote account for execution on the remote chain.
* @param msgs - records for the transaction
* @returns acknowledgement string
*/
executeTx: (msgs: TypedJson[]) => Promise<string>;
export interface IcaAccountMethods {
/**
* Submit a transaction on behalf of the remote account for execution on the remote chain.
* @param msgs - records for the transaction
Expand Down Expand Up @@ -267,6 +262,23 @@ export interface IcaAccount {
* @throws {Error} if connection is currently active
*/
reactivate: () => Promise<void>;
}

/**
* Low level object that supports queries and operations for an account on a remote chain.
*/
export interface IcaAccount extends IcaAccountMethods {
/**
* @returns the address of the account on the remote chain
*/
getAddress: () => ChainAddress;

/**
* Submit a transaction on behalf of the remote account for execution on the remote chain.
* @param msgs - records for the transaction
* @returns acknowledgement string
*/
executeTx: (msgs: TypedJson[]) => Promise<string>;
/** @returns the address of the remote channel */
getRemoteAddress: () => RemoteIbcAddress;
/** @returns the address of the local channel */
Expand All @@ -280,16 +292,22 @@ export interface LiquidStakingMethods {
liquidStake: (amount: AmountArg) => Promise<void>;
}

// TODO support StakingAccountQueries
/** Methods supported only on Agoric chain accounts */
export interface LocalAccountMethods {
export interface LocalAccountMethods extends StakingAccountActions {
/** deposit payment (from zoe, for example) to the account */
deposit: (payment: Payment<'nat'>) => Promise<void>;
/** withdraw a Payment from the account */
withdraw: (amount: Amount<'nat'>) => Promise<Payment<'nat'>>;
/**
* Register a handler that receives an event each time ICS-20 transfers are
* sent or received by the underlying account. Each account may be associated
* with at most one handler at a given time.
* sent or received by the underlying account.
*
* Handler includes {@link VTransferIBCEvent} and
* {@link FungibleTokenPacketData} that can be used for application logic.
*
* Each account may be associated with at most one handler at a given time.
*
* Does not grant the handler the ability to intercept a transfer. For a
* blocking handler, aka 'IBC Hooks', leverage `registerActiveTap` from
* `transferMiddleware` directly.
Expand Down Expand Up @@ -320,16 +338,12 @@ export interface IBCMsgTransferOptions {
* @see {OrchestrationAccountI}
*/
export type CosmosChainAccountMethods<CCI extends CosmosChainInfo> =
(CCI extends {
icaEnabled: true;
}
? IcaAccount
: {}) &
CCI extends {
stakingTokens: {};
}
? StakingAccountActions & StakingAccountQueries
: {};
IcaAccountMethods &
(CCI extends {
stakingTokens: {};
}
? StakingAccountActions & StakingAccountQueries
: {});

export type ICQQueryFunction = (
msgs: JsonSafe<RequestQuery>[],
Expand Down
9 changes: 5 additions & 4 deletions packages/orchestration/src/exos/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Exo structure

Last verified 2024-09-06
Last verified 2024-10-30

```mermaid
classDiagram
Expand Down Expand Up @@ -52,9 +52,9 @@ classDiagram
%% In other vats
class Port {
getLocalAddress()
addListener()
connect()
getLocalAddress()
removeListener()
revoke()
}
Expand All @@ -76,9 +76,8 @@ classDiagram
deposit()
executeTx()
getBalance()
withdraw()
executeTx()
monitorTransfers()
withdraw()
}
%% In api consumer vats
Expand Down Expand Up @@ -113,12 +112,14 @@ classDiagram
timer: Timer
topicKit: RecorderKit<OrchestrationAccountNotification>
asContinuingOffer()
deactivate()
delegate()
executeEncodedTx()
getAddress()
getBalance()
getBalances()
getPublicTopics()
reactivate()
redelegate()
send()
sendAll()
Expand Down
12 changes: 9 additions & 3 deletions packages/orchestration/src/exos/orchestrator.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
* @import {CosmosInterchainService} from './exo-interfaces.js';
* @import {MakeLocalChainFacade} from './local-chain-facade.js';
* @import {MakeRemoteChainFacade} from './remote-chain-facade.js';
* @import {Chain, ChainInfo, IBCConnectionInfo, Orchestrator} from '../types.js';
* @import {Chain, ChainInfo, IBCConnectionInfo, KnownChains, Orchestrator} from '../types.js';
*/

const { Vow$ } = NetworkShape; // TODO #9611
Expand Down Expand Up @@ -148,14 +148,20 @@ const prepareOrchestratorKit = (
if (maybeChain.pending) {
throw Fail`wait until getChain(${q(chainName)}) completes before getDenomInfo(${q(denom)})`;
}
const chain = maybeChain.value;
const chain =
/** @type {HostInterface<Chain<KnownChains[keyof KnownChains]>>} */ (
maybeChain.value
);
chainByName.has(baseName) ||
Fail`use getChain(${q(baseName)}) before getDenomInfo(${q(denom)})`;
const maybeBase = chainByName.get(baseName);
if (maybeBase.pending) {
throw Fail`wait until getChain(${q(baseName)}) completes before getDenomInfo(${q(denom)})`;
}
const base = maybeBase.value;
const base =
/** @type {HostInterface<Chain<KnownChains[keyof KnownChains]>>} */ (
maybeBase.value
);
return harden({ chain, base, brand, baseDenom });
},
/** @type {HostOf<Orchestrator['asAmount']>} */
Expand Down
7 changes: 2 additions & 5 deletions packages/orchestration/src/orchestration-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@
import type { Amount, Brand, NatAmount } from '@agoric/ertp/src/types.js';
import type { CurrentWalletRecord } from '@agoric/smart-wallet/src/smartWallet.js';
import type { Timestamp } from '@agoric/time';
import type {
LocalChainAccount,
QueryManyFn,
} from '@agoric/vats/src/localchain.js';
import type { QueryManyFn } from '@agoric/vats/src/localchain.js';
import type { ResolvedPublicTopic } from '@agoric/zoe/src/contractSupport/topics.js';
import type { Passable } from '@endo/marshal';
import type {
Expand Down Expand Up @@ -76,7 +73,7 @@ export type ChainAddress = {
export type OrchestrationAccount<CI extends ChainInfo> = OrchestrationAccountI &
(CI extends CosmosChainInfo
? CI['chainId'] extends `agoric${string}`
? CosmosChainAccountMethods<CI> & LocalAccountMethods
? LocalAccountMethods
: CosmosChainAccountMethods<CI>
: {});

Expand Down
55 changes: 54 additions & 1 deletion packages/orchestration/test/types.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/

import type { HostInterface, HostOf } from '@agoric/async-flow';
import { type JsonSafe, typedJson } from '@agoric/cosmic-proto';
import { type AnyJson, type JsonSafe, typedJson } from '@agoric/cosmic-proto';
import type {
QueryAllBalancesResponse,
QueryBalanceResponse,
Expand All @@ -14,10 +14,16 @@ import type { Vow, VowTools } from '@agoric/vow';
import type { ResolvedPublicTopic } from '@agoric/zoe/src/contractSupport/topics.js';
import type { Passable } from '@endo/marshal';
import { expectAssignable, expectNotType, expectType } from 'tsd';
import type { TxBody } from '@agoric/cosmic-proto/cosmos/tx/v1beta1/tx.js';
import type {
TargetApp,
TargetRegistration,
} from '@agoric/vats/src/bridge-target.js';
import { prepareCosmosOrchestrationAccount } from '../src/exos/cosmos-orchestration-account.js';
import type { LocalOrchestrationAccountKit } from '../src/exos/local-orchestration-account.js';
import type { OrchestrationFacade } from '../src/facade.js';
import type {
AmountArg,
Chain,
ChainAddress,
ChainInfo,
Expand Down Expand Up @@ -267,3 +273,50 @@ expectNotType<CosmosValidatorAddress>(chainAddr);
expectAssignable<Passable>(addr as CosmosValidatorAddress);
expectAssignable<Passable>(denomAmount as DenomAmount);
}

// Test LocalAccountMethods
{
type ChainFacade = Chain<CosmosChainInfo & { chainId: 'agoric-3' }>;
const remoteChain: ChainFacade = null as any;

const account = await remoteChain.makeAccount();

// Verify monitorTransfers is available
expectType<(tap: TargetApp) => Promise<TargetRegistration>>(
account.monitorTransfers,
);

// Verify StakingAccountActions are available (StakingAccountQueries not yet supported)
expectType<
(validator: CosmosValidatorAddress, amount: AmountArg) => Promise<void>
>(account.delegate);

// @ts-expect-error executeEncodedTx not available on localAccount
expectType<() => Promise<string>>(account.executeEncodedTx);
}

// Test CosmosChainAccountMethods
{
type ChainFacade = Chain<
CosmosChainInfo & {
chainId: 'cosmoshub-4';
stakingTokens: [{ denom: 'uatom' }];
}
>;
const remoteChain: ChainFacade = null as any;

const account = await remoteChain.makeAccount();

// Verify executeEncodedTx is available
expectType<
(
msgs: AnyJson[],
opts?: Partial<Omit<TxBody, 'messages'>>,
) => Promise<string>
>(account.executeEncodedTx);

// Verify delegate is available via stakingTokens parameter
expectType<
(validator: CosmosValidatorAddress, amount: AmountArg) => Promise<void>
>(account.delegate);
}

0 comments on commit 3262f6c

Please sign in to comment.