Skip to content

Commit

Permalink
refactor(orchestration): prefer ChainAddress object to string
Browse files Browse the repository at this point in the history
  • Loading branch information
0xpatrickdev committed May 2, 2024
1 parent 27be06b commit a6360a5
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 36 deletions.
2 changes: 1 addition & 1 deletion packages/boot/test/bootstrapTests/test-orchestration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ test.serial('stakeAtom - smart wallet', async t => {
invitationSpec: {
source: 'agoricContract',
instancePath: ['stakeAtom'],
callPipe: [['makeNewAccountInvitation']],
callPipe: [['makeMakeAccountInvitation']],
},
proposal: {},
});
Expand Down
19 changes: 9 additions & 10 deletions packages/boot/test/bootstrapTests/test-vat-orchestration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,22 +76,21 @@ test('makeAccount returns an ICA connection', async t => {
matches(account, M.remotable('ChainAccount')),
'account is a remotable',
);
const [remoteAddress, localAddress, accountAddress, port] = await Promise.all(
[
EV(account).getRemoteAddress(),
EV(account).getLocalAddress(),
EV(account).getAddress(),
EV(account).getPort(),
],
);
const [remoteAddress, localAddress, chainAddress, port] = await Promise.all([
EV(account).getRemoteAddress(),
EV(account).getLocalAddress(),
EV(account).getAddress(),
EV(account).getPort(),
]);
t.regex(remoteAddress, /icahost/);
t.regex(localAddress, /icacontroller/);
t.regex(accountAddress, /cosmos1/);
t.regex(chainAddress.address, /cosmos1/);
t.regex(chainAddress.chainId, /FIXME/); // TODO, use a real chainId #9063
t.truthy(matches(port, M.remotable('Port')));
t.log('ICA Account Addresses', {
remoteAddress,
localAddress,
accountAddress,
chainAddress,
});
});

Expand Down
4 changes: 2 additions & 2 deletions packages/orchestration/src/examples/stakeAtom.contract.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,14 @@ export const start = async (zcf, privateArgs, baggage) => {
'StakeAtom',
M.interface('StakeAtomI', {
makeAccount: M.callWhen().returns(M.remotable('ChainAccount')),
makeNewAccountInvitation: M.call().returns(M.promise()),
makeMakeAccountInvitation: M.call().returns(M.promise()),
}),
{
async makeAccount() {
trace('makeAccount');
return makeAccount().then(({ account }) => account);
},
makeNewAccountInvitation() {
makeMakeAccountInvitation() {
trace('makeCreateAccountInvitation');
return zcf.makeInvitation(
async seat => {
Expand Down
19 changes: 9 additions & 10 deletions packages/orchestration/src/exos/stakingAccountKit.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ import { E } from '@endo/far';
import { Any } from '@agoric/cosmic-proto/google/protobuf/any';

/**
* @import { ChainAddress } from '../types.js';
* @import { ChainAccountKit } from '../service.js';
* @import { ChainAccount, ChainAddress } from '../types.js';
* @import { RecorderKit, MakeRecorderKit } from '@agoric/zoe/src/contractSupport/recorder.js';
* @import { Baggage } from '@agoric/swingset-liveslots';
* @import {AnyJson} from '@agoric/cosmic-proto';
Expand All @@ -26,14 +25,14 @@ const trace = makeTracer('StakingAccountHolder');
const { Fail } = assert;
/**
* @typedef {object} StakingAccountNotification
* @property {ChainAddress['address']} address
* @property {ChainAddress} chainAddress
*/

/**
* @typedef {{
* topicKit: RecorderKit<StakingAccountNotification>;
* account: ChainAccountKit['account'];
* address: ChainAddress['address'];
* account: ChainAccount;
* chainAddress: ChainAddress;
* }} State
*/

Expand Down Expand Up @@ -70,16 +69,16 @@ export const prepareStakingAccountKit = (baggage, makeRecorderKit, zcf) => {
}),
},
/**
* @param {ChainAccountKit['account']} account
* @param {ChainAccount} account
* @param {StorageNode} storageNode
* @param {ChainAddress['address']} address
* @param {ChainAddress} chainAddress
* @returns {State}
*/
(account, storageNode, address) => {
(account, storageNode, chainAddress) => {
// must be the fully synchronous maker because the kit is held in durable state
const topicKit = makeRecorderKit(storageNode, PUBLIC_TOPICS.account[1]);

return { account, address, topicKit };
return { account, chainAddress, topicKit };
},
{
helper: {
Expand Down Expand Up @@ -110,7 +109,7 @@ export const prepareStakingAccountKit = (baggage, makeRecorderKit, zcf) => {
};

const account = this.facets.helper.owned();
const delegatorAddress = this.state.address;
const delegatorAddress = this.state.chainAddress.address;

const result = await E(account).executeEncodedTx([
/** @type {AnyJson} */ (
Expand Down
35 changes: 26 additions & 9 deletions packages/orchestration/src/service.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { makeTxPacket, parsePacketAck } from './utils/tx.js';
* @import { IBCConnectionID } from '@agoric/vats';
* @import { Zone } from '@agoric/base-zone';
* @import { TxBody } from '@agoric/cosmic-proto/cosmos/tx/v1beta1/tx.js';
* @import { AttenuatedNetwork, ChainAccount, ChainAddress } from './types.js';
* @import { ChainAccount, ChainAddress } from './types.js';
*/

const { Fail, bare } = assert;
Expand Down Expand Up @@ -58,8 +58,17 @@ export const Proto3Shape = {
value: M.string(),
};

export const ChainAddressShape = {
address: M.string(),
chainId: M.string(),
addressEncoding: M.string(),
};

/** @typedef {'UNPARSABLE_CHAIN_ADDRESS'} UnparsableChainAddress */
const UNPARSABLE_CHAIN_ADDRESS = 'UNPARSABLE_CHAIN_ADDRESS';

export const ChainAccountI = M.interface('ChainAccount', {
getAddress: M.call().returns(M.string()),
getAddress: M.call().returns(ChainAddressShape),
getLocalAddress: M.call().returns(M.string()),
getRemoteAddress: M.call().returns(M.string()),
getPort: M.call().returns(M.remotable('Port')),
Expand Down Expand Up @@ -96,27 +105,27 @@ const prepareChainAccount = zone =>
* localAddress: string | undefined;
* requestedRemoteAddress: string;
* remoteAddress: string | undefined;
* address: ChainAddress['address'] | undefined;
* chainAddress: ChainAddress | undefined;
* }}
*/ (
harden({
port,
connection: undefined,
requestedRemoteAddress,
remoteAddress: undefined,
address: undefined,
chainAddress: undefined,
localAddress: undefined,
})
),
{
account: {
/**
* @returns {ChainAddress['address']} the address of the account on the chain
* @returns {ChainAddress}
*/
getAddress() {
return NonNullish(
this.state.address,
'Error parsing account address from remote address',
this.state.chainAddress,
'ICA channel creation acknowledgement not yet received.',
);
},
getLocalAddress() {
Expand Down Expand Up @@ -194,7 +203,15 @@ const prepareChainAccount = zone =>
this.state.remoteAddress = remoteAddr;
this.state.localAddress = localAddr;
// XXX parseAddress currently throws, should it return '' instead?
this.state.address = parseAddress(remoteAddr);
this.state.chainAddress = harden({
address: parseAddress(remoteAddr) || UNPARSABLE_CHAIN_ADDRESS,
// TODO get this from `Chain` object #9063
// XXX how do we get a chainId for an unknown chain? seems it may need to be a user supplied arg
chainId: 'FIXME',
addressEncoding: 'bech32',
});
trace('got chainAddress', this.state.chainAddress);
trace('parseAddress(remoteAddr)', parseAddress(remoteAddr));
},
async onClose(_connection, reason) {
trace(`ICA Channel closed. Reason: ${reason}`);
Expand Down Expand Up @@ -252,7 +269,7 @@ const prepareOrchestration = (zone, createChainAccount) =>
* the counterparty connection_id
* @param {IBCConnectionID} controllerConnectionId
* self connection_id
* @returns {Promise<ChainAccountKit['account']>}
* @returns {Promise<ChainAccount>}
*/
async makeAccount(hostConnectionId, controllerConnectionId) {
const port = await this.facets.self.bindPort();
Expand Down
7 changes: 3 additions & 4 deletions packages/orchestration/src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -419,12 +419,11 @@ export type TransferMsg = {
data?: object;
};

// Example
// await icaNoble.transferSteps(usdcAmt,
// osmosisSwap(tiaBrand, { pool: 1224, slippage: 0.05 }, icaCel.getChainAddress()));

/**
* @param pool - Required. Pool number
* @example
* await icaNoble.transferSteps(usdcAmt,
* osmosisSwap(tiaBrand, { pool: 1224, slippage: 0.05 }, icaCel.getAddress()));
*/
export type OsmoSwapOptions = {
pool: string;
Expand Down

0 comments on commit a6360a5

Please sign in to comment.