@agoric/orchestration 0.1.1-dev-8e82183.0 → 0.1.1-dev-5a4779a.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agoric/orchestration",
3
- "version": "0.1.1-dev-8e82183.0+8e82183",
3
+ "version": "0.1.1-dev-5a4779a.0+5a4779a",
4
4
  "description": "Chain abstraction for Agoric's orchestration clients",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -29,18 +29,18 @@
29
29
  },
30
30
  "homepage": "https://github.com/Agoric/agoric-sdk#readme",
31
31
  "dependencies": {
32
- "@agoric/assert": "0.6.1-dev-8e82183.0+8e82183",
33
- "@agoric/cosmic-proto": "0.4.1-dev-8e82183.0+8e82183",
34
- "@agoric/ertp": "0.16.3-dev-8e82183.0+8e82183",
35
- "@agoric/internal": "0.3.3-dev-8e82183.0+8e82183",
36
- "@agoric/network": "0.1.1-dev-8e82183.0+8e82183",
37
- "@agoric/notifier": "0.6.3-dev-8e82183.0+8e82183",
38
- "@agoric/store": "0.9.3-dev-8e82183.0+8e82183",
39
- "@agoric/time": "0.3.3-dev-8e82183.0+8e82183",
40
- "@agoric/vat-data": "0.5.3-dev-8e82183.0+8e82183",
41
- "@agoric/vats": "0.15.2-dev-8e82183.0+8e82183",
42
- "@agoric/zoe": "0.26.3-dev-8e82183.0+8e82183",
43
- "@agoric/zone": "0.2.3-dev-8e82183.0+8e82183",
32
+ "@agoric/assert": "0.6.1-dev-5a4779a.0+5a4779a",
33
+ "@agoric/cosmic-proto": "0.4.1-dev-5a4779a.0+5a4779a",
34
+ "@agoric/ertp": "0.16.3-dev-5a4779a.0+5a4779a",
35
+ "@agoric/internal": "0.3.3-dev-5a4779a.0+5a4779a",
36
+ "@agoric/network": "0.1.1-dev-5a4779a.0+5a4779a",
37
+ "@agoric/notifier": "0.6.3-dev-5a4779a.0+5a4779a",
38
+ "@agoric/store": "0.9.3-dev-5a4779a.0+5a4779a",
39
+ "@agoric/time": "0.3.3-dev-5a4779a.0+5a4779a",
40
+ "@agoric/vat-data": "0.5.3-dev-5a4779a.0+5a4779a",
41
+ "@agoric/vats": "0.15.2-dev-5a4779a.0+5a4779a",
42
+ "@agoric/zoe": "0.26.3-dev-5a4779a.0+5a4779a",
43
+ "@agoric/zone": "0.2.3-dev-5a4779a.0+5a4779a",
44
44
  "@endo/base64": "^1.0.4",
45
45
  "@endo/far": "^1.1.1",
46
46
  "@endo/marshal": "^1.4.1",
@@ -82,5 +82,5 @@
82
82
  "typeCoverage": {
83
83
  "atLeast": 96.39
84
84
  },
85
- "gitHead": "8e821833bce43984d493d297c0513b474bb4532b"
85
+ "gitHead": "5a4779a5b0240bccd150607474d80beac23da3cd"
86
86
  }
@@ -47,17 +47,17 @@ export const start = async (zcf, privateArgs, baggage) => {
47
47
  zcf,
48
48
  );
49
49
 
50
- async function createAccount() {
51
- const account = await E(orchestration).createAccount(
50
+ async function makeAccount() {
51
+ const account = await E(orchestration).makeAccount(
52
52
  hostConnectionId,
53
53
  controllerConnectionId,
54
54
  );
55
- const accountAddress = await E(account).getAccountAddress();
56
- trace('account address', accountAddress);
55
+ const address = await E(account).getAddress();
56
+ trace('chain address', address);
57
57
  const { holder, invitationMakers } = makeStakingAccountKit(
58
58
  account,
59
59
  storageNode,
60
- accountAddress,
60
+ address,
61
61
  );
62
62
  return {
63
63
  publicSubscribers: holder.getPublicTopics(),
@@ -69,20 +69,20 @@ export const start = async (zcf, privateArgs, baggage) => {
69
69
  const publicFacet = zone.exo(
70
70
  'StakeAtom',
71
71
  M.interface('StakeAtomI', {
72
- createAccount: M.callWhen().returns(M.remotable('ChainAccount')),
73
- makeCreateAccountInvitation: M.call().returns(M.promise()),
72
+ makeAccount: M.callWhen().returns(M.remotable('ChainAccount')),
73
+ makeAcountInvitationMaker: M.call().returns(M.promise()),
74
74
  }),
75
75
  {
76
- async createAccount() {
77
- trace('createAccount');
78
- return createAccount().then(({ account }) => account);
76
+ async makeAccount() {
77
+ trace('makeAccount');
78
+ return makeAccount().then(({ account }) => account);
79
79
  },
80
- makeCreateAccountInvitation() {
80
+ makeAcountInvitationMaker() {
81
81
  trace('makeCreateAccountInvitation');
82
82
  return zcf.makeInvitation(
83
83
  async seat => {
84
84
  seat.exit();
85
- return createAccount();
85
+ return makeAccount();
86
86
  },
87
87
  'wantStakingAccount',
88
88
  undefined,
@@ -48,7 +48,7 @@ export const start = async (zcf, privateArgs, baggage) => {
48
48
  const { give } = seat.getProposal();
49
49
  trace('makeStakeBldInvitation', give);
50
50
  // XXX type appears local but it's remote
51
- const account = await E(privateArgs.localchain).createAccount();
51
+ const account = await E(privateArgs.localchain).makeAccount();
52
52
  const lcaSeatKit = zcf.makeEmptySeatKit();
53
53
  atomicTransfer(zcf, seat, lcaSeatKit.zcfSeat, give);
54
54
  seat.exit();
@@ -48,11 +48,11 @@ export const start = async (zcf, privateArgs) => {
48
48
  const agoric = await orch.getChain('agoric');
49
49
 
50
50
  const [celestiaAccount, localAccount] = await Promise.all([
51
- celestia.createAccount(),
52
- agoric.createAccount(),
51
+ celestia.makeAccount(),
52
+ agoric.makeAccount(),
53
53
  ]);
54
54
 
55
- const tiaAddress = await celestiaAccount.getChainAddress();
55
+ const tiaAddress = await celestiaAccount.getAddress();
56
56
 
57
57
  // deposit funds from user seat to LocalChainAccount
58
58
  const seatKit = zcf.makeEmptySeatKit();
@@ -47,21 +47,19 @@ export const start = async (zcf, privateArgs) => {
47
47
  // ??? could these be passed in? It would reduce the size of this handler,
48
48
  // keeping it focused on long-running operations.
49
49
  const celestia = await orch.getChain('celestia');
50
- const celestiaAccount = await celestia.createAccount();
50
+ const celestiaAccount = await celestia.makeAccount();
51
51
 
52
52
  const delegations = await celestiaAccount.getDelegations();
53
- const [undelegation] = await celestiaAccount.undelegate(delegations);
54
-
55
53
  // wait for the undelegations to be complete (may take weeks)
56
- await undelegation.completion;
54
+ await celestiaAccount.undelegate(delegations);
57
55
 
58
56
  // ??? should this be synchronous? depends on how names are resolved.
59
57
  const stride = await orch.getChain('stride');
60
- const strideAccount = await stride.createAccount();
58
+ const strideAccount = await stride.makeAccount();
61
59
 
62
60
  // TODO the `TIA` string actually needs to be the Brand from AgoricNames
63
61
  const tiaAmt = await celestiaAccount.getBalance('TIA');
64
- await celestiaAccount.transfer(tiaAmt, strideAccount.getChainAddress());
62
+ await celestiaAccount.transfer(tiaAmt, strideAccount.getAddress());
65
63
 
66
64
  await strideAccount.liquidStake(tiaAmt);
67
65
  },
@@ -0,0 +1,200 @@
1
+ // @ts-check
2
+ /** @file Orchestration service */
3
+ import { NonNullish } from '@agoric/assert';
4
+ import { makeTracer } from '@agoric/internal';
5
+
6
+ // XXX ambient types runtime imports until https://github.com/Agoric/agoric-sdk/issues/6512
7
+ import '@agoric/network/exported.js';
8
+
9
+ import { V as E } from '@agoric/vat-data/vow.js';
10
+ import { M } from '@endo/patterns';
11
+ import { PaymentShape, PurseShape } from '@agoric/ertp';
12
+ import { InvitationShape } from '@agoric/zoe/src/typeGuards.js';
13
+ import { parseAddress } from '../utils/address.js';
14
+ import { makeTxPacket, parsePacketAck } from '../utils/tx.js';
15
+
16
+ /**
17
+ * @import { Connection, Port } from '@agoric/network';
18
+ * @import { Remote } from '@agoric/vow';
19
+ * @import { Zone } from '@agoric/base-zone';
20
+ * @import { AnyJson } from '@agoric/cosmic-proto';
21
+ * @import { TxBody } from '@agoric/cosmic-proto/cosmos/tx/v1beta1/tx.js';
22
+ * @import { LocalIbcAddress, RemoteIbcAddress } from '@agoric/vats/tools/ibc-utils.js';
23
+ * @import { ChainAddress } from '../types.js';
24
+ */
25
+
26
+ const { Fail } = assert;
27
+ const trace = makeTracer('ChainAccount');
28
+
29
+ export const Proto3Shape = {
30
+ typeUrl: M.string(),
31
+ value: M.string(),
32
+ };
33
+
34
+ export const ChainAddressShape = {
35
+ address: M.string(),
36
+ chainId: M.string(),
37
+ addressEncoding: M.string(),
38
+ };
39
+
40
+ /** @typedef {'UNPARSABLE_CHAIN_ADDRESS'} UnparsableChainAddress */
41
+ const UNPARSABLE_CHAIN_ADDRESS = 'UNPARSABLE_CHAIN_ADDRESS';
42
+
43
+ export const ChainAccountI = M.interface('ChainAccount', {
44
+ getAddress: M.call().returns(ChainAddressShape),
45
+ getLocalAddress: M.call().returns(M.string()),
46
+ getRemoteAddress: M.call().returns(M.string()),
47
+ getPort: M.call().returns(M.remotable('Port')),
48
+ executeTx: M.call(M.arrayOf(M.record())).returns(M.promise()),
49
+ executeEncodedTx: M.call(M.arrayOf(Proto3Shape))
50
+ .optional(M.record())
51
+ .returns(M.promise()),
52
+ close: M.callWhen().returns(M.undefined()),
53
+ deposit: M.callWhen(PaymentShape).returns(M.undefined()),
54
+ getPurse: M.callWhen().returns(PurseShape),
55
+ prepareTransfer: M.callWhen().returns(InvitationShape),
56
+ });
57
+
58
+ export const ConnectionHandlerI = M.interface('ConnectionHandler', {
59
+ onOpen: M.callWhen(M.any(), M.string(), M.string(), M.any()).returns(M.any()),
60
+ onClose: M.callWhen(M.any(), M.any(), M.any()).returns(M.any()),
61
+ onReceive: M.callWhen(M.any(), M.string()).returns(M.any()),
62
+ });
63
+
64
+ /** @param {Zone} zone */
65
+ export const prepareChainAccountKit = zone =>
66
+ zone.exoClassKit(
67
+ 'ChainAccount',
68
+ { account: ChainAccountI, connectionHandler: ConnectionHandlerI },
69
+ /**
70
+ * @param {Port} port
71
+ * @param {string} requestedRemoteAddress
72
+ */
73
+ (port, requestedRemoteAddress) =>
74
+ /**
75
+ * @type {{
76
+ * port: Port;
77
+ * connection: Remote<Connection> | undefined;
78
+ * localAddress: LocalIbcAddress | undefined;
79
+ * requestedRemoteAddress: string;
80
+ * remoteAddress: RemoteIbcAddress | undefined;
81
+ * chainAddress: ChainAddress | undefined;
82
+ * }}
83
+ */ (
84
+ harden({
85
+ port,
86
+ connection: undefined,
87
+ requestedRemoteAddress,
88
+ remoteAddress: undefined,
89
+ chainAddress: undefined,
90
+ localAddress: undefined,
91
+ })
92
+ ),
93
+ {
94
+ account: {
95
+ /**
96
+ * @returns {ChainAddress}
97
+ */
98
+ getAddress() {
99
+ return NonNullish(
100
+ this.state.chainAddress,
101
+ 'ICA channel creation acknowledgement not yet received.',
102
+ );
103
+ },
104
+ getLocalAddress() {
105
+ return NonNullish(
106
+ this.state.localAddress,
107
+ 'local address not available',
108
+ );
109
+ },
110
+ getRemoteAddress() {
111
+ return NonNullish(
112
+ this.state.remoteAddress,
113
+ 'remote address not available',
114
+ );
115
+ },
116
+ getPort() {
117
+ return this.state.port;
118
+ },
119
+ executeTx() {
120
+ throw new Error('not yet implemented');
121
+ },
122
+ /**
123
+ * Submit a transaction on behalf of the remote account for execution on the remote chain.
124
+ * @param {AnyJson[]} msgs
125
+ * @param {Omit<TxBody, 'messages'>} [opts]
126
+ * @returns {Promise<string>} - base64 encoded bytes string. Can be decoded using the corresponding `Msg*Response` object.
127
+ * @throws {Error} if packet fails to send or an error is returned
128
+ */
129
+ executeEncodedTx(msgs, opts) {
130
+ const { connection } = this.state;
131
+ if (!connection) throw Fail`connection not available`;
132
+ return E.when(
133
+ E(connection).send(makeTxPacket(msgs, opts)),
134
+ // if parsePacketAck cannot find a `result` key, it throws
135
+ ack => parsePacketAck(ack),
136
+ );
137
+ },
138
+ /**
139
+ * Close the remote account
140
+ */
141
+ async close() {
142
+ /// XXX what should the behavior be here? and `onClose`?
143
+ // - retrieve assets?
144
+ // - revoke the port?
145
+ const { connection } = this.state;
146
+ if (!connection) throw Fail`connection not available`;
147
+ await E(connection).close();
148
+ },
149
+ async deposit(payment) {
150
+ console.log('deposit got', payment);
151
+ throw new Error('not yet implemented');
152
+ },
153
+ /**
154
+ * get Purse for a brand to .withdraw() a Payment from the account
155
+ * @param {Brand} brand
156
+ */
157
+ async getPurse(brand) {
158
+ console.log('getPurse got', brand);
159
+ throw new Error('not yet implemented');
160
+ },
161
+
162
+ /* transfer account to new holder */
163
+ async prepareTransfer() {
164
+ throw new Error('not yet implemented');
165
+ },
166
+ },
167
+ connectionHandler: {
168
+ /**
169
+ * @param {Remote<Connection>} connection
170
+ * @param {LocalIbcAddress} localAddr
171
+ * @param {RemoteIbcAddress} remoteAddr
172
+ */
173
+ async onOpen(connection, localAddr, remoteAddr) {
174
+ trace(`ICA Channel Opened for ${localAddr} at ${remoteAddr}`);
175
+ this.state.connection = connection;
176
+ this.state.remoteAddress = remoteAddr;
177
+ this.state.localAddress = localAddr;
178
+ // XXX parseAddress currently throws, should it return '' instead?
179
+ this.state.chainAddress = harden({
180
+ address: parseAddress(remoteAddr) || UNPARSABLE_CHAIN_ADDRESS,
181
+ // TODO get this from `Chain` object #9063
182
+ // XXX how do we get a chainId for an unknown chain? seems it may need to be a user supplied arg
183
+ chainId: 'FIXME',
184
+ addressEncoding: 'bech32',
185
+ });
186
+ },
187
+ async onClose(_connection, reason) {
188
+ trace(`ICA Channel closed. Reason: ${reason}`);
189
+ // XXX handle connection closing
190
+ // XXX is there a scenario where a connection will unexpectedly close? _I think yes_
191
+ },
192
+ async onReceive(connection, bytes) {
193
+ trace(`ICA Channel onReceive`, connection, bytes);
194
+ return '';
195
+ },
196
+ },
197
+ },
198
+ );
199
+
200
+ /** @typedef {ReturnType<ReturnType<typeof prepareChainAccountKit>>} ChainAccountKit */
@@ -25,14 +25,14 @@ const trace = makeTracer('StakingAccountHolder');
25
25
  const { Fail } = assert;
26
26
  /**
27
27
  * @typedef {object} StakingAccountNotification
28
- * @property {string} address
28
+ * @property {ChainAddress} chainAddress
29
29
  */
30
30
 
31
31
  /**
32
32
  * @typedef {{
33
33
  * topicKit: RecorderKit<StakingAccountNotification>;
34
34
  * account: ChainAccount;
35
- * chainAddress: string;
35
+ * chainAddress: ChainAddress;
36
36
  * }} State
37
37
  */
38
38
 
@@ -71,7 +71,7 @@ export const prepareStakingAccountKit = (baggage, makeRecorderKit, zcf) => {
71
71
  /**
72
72
  * @param {ChainAccount} account
73
73
  * @param {StorageNode} storageNode
74
- * @param {string} chainAddress
74
+ * @param {ChainAddress} chainAddress
75
75
  * @returns {State}
76
76
  */
77
77
  (account, storageNode, chainAddress) => {
@@ -94,7 +94,7 @@ export const prepareStakingAccountKit = (baggage, makeRecorderKit, zcf) => {
94
94
  return this.state.topicKit.recorder;
95
95
  },
96
96
  // TODO move this beneath the Orchestration abstraction,
97
- // to the OrchestrationAccount provided by createAccount()
97
+ // to the OrchestrationAccount provided by makeAccount()
98
98
  /**
99
99
  * _Assumes users has already sent funds to their ICA, until #9193
100
100
  * @param {string} validatorAddress
@@ -109,7 +109,7 @@ export const prepareStakingAccountKit = (baggage, makeRecorderKit, zcf) => {
109
109
  };
110
110
 
111
111
  const account = this.facets.helper.owned();
112
- const delegatorAddress = this.state.chainAddress;
112
+ const delegatorAddress = this.state.chainAddress.address;
113
113
 
114
114
  const result = await E(account).executeEncodedTx([
115
115
  /** @type {AnyJson} */ (
package/src/service.js CHANGED
@@ -1,31 +1,22 @@
1
1
  // @ts-check
2
2
  /** @file Orchestration service */
3
- import { NonNullish } from '@agoric/assert';
4
- import { makeTracer } from '@agoric/internal';
5
3
 
6
4
  // XXX ambient types runtime imports until https://github.com/Agoric/agoric-sdk/issues/6512
7
5
  import '@agoric/network/exported.js';
8
6
 
9
7
  import { V as E } from '@agoric/vat-data/vow.js';
10
8
  import { M } from '@endo/patterns';
11
- import { PaymentShape, PurseShape } from '@agoric/ertp';
12
- import { InvitationShape } from '@agoric/zoe/src/typeGuards.js';
13
- import { makeICAConnectionAddress, parseAddress } from './utils/address.js';
14
- import { makeTxPacket, parsePacketAck } from './utils/tx.js';
9
+ import { prepareChainAccountKit } from './exos/chainAccountKit.js';
10
+ import { makeICAConnectionAddress } from './utils/address.js';
15
11
 
16
12
  /**
17
- * @import {Connection, Port, PortAllocator} from '@agoric/network';
18
- * @import {Remote} from '@agoric/vow';
13
+ * @import { PortAllocator} from '@agoric/network';
19
14
  * @import { IBCConnectionID } from '@agoric/vats';
20
15
  * @import { Zone } from '@agoric/base-zone';
21
- * @import { TxBody } from '@agoric/cosmic-proto/cosmos/tx/v1beta1/tx.js';
22
- * @import { AttenuatedNetwork, ChainAccount, ChainAddress } from './types.js';
16
+ * @import { ChainAccount } from './types.js';
23
17
  */
24
18
 
25
19
  const { Fail, bare } = assert;
26
- const trace = makeTracer('Orchestration');
27
-
28
- /** @import {AnyJson} from '@agoric/cosmic-proto'; */
29
20
 
30
21
  /**
31
22
  * @typedef {object} OrchestrationPowers
@@ -53,173 +44,17 @@ const getPower = (powers, name) => {
53
44
  return /** @type {OrchestrationPowers[K]} */ (powers.get(name));
54
45
  };
55
46
 
56
- export const Proto3Shape = {
57
- typeUrl: M.string(),
58
- value: M.string(),
59
- };
60
-
61
- export const ChainAccountI = M.interface('ChainAccount', {
62
- getAccountAddress: M.call().returns(M.string()),
63
- getLocalAddress: M.call().returns(M.string()),
64
- getRemoteAddress: M.call().returns(M.string()),
65
- getPort: M.call().returns(M.remotable('Port')),
66
- executeTx: M.call(M.arrayOf(M.record())).returns(M.promise()),
67
- executeEncodedTx: M.call(M.arrayOf(Proto3Shape))
68
- .optional(M.record())
69
- .returns(M.promise()),
70
- close: M.callWhen().returns(M.undefined()),
71
- deposit: M.callWhen(PaymentShape).returns(M.undefined()),
72
- getPurse: M.callWhen().returns(PurseShape),
73
- prepareTransfer: M.callWhen().returns(InvitationShape),
74
- });
75
-
76
- export const ConnectionHandlerI = M.interface('ConnectionHandler', {
77
- onOpen: M.callWhen(M.any(), M.string(), M.string(), M.any()).returns(M.any()),
78
- onClose: M.callWhen(M.any(), M.any(), M.any()).returns(M.any()),
79
- onReceive: M.callWhen(M.any(), M.string()).returns(M.any()),
80
- });
81
-
82
- /** @param {Zone} zone */
83
- const prepareChainAccount = zone =>
84
- zone.exoClassKit(
85
- 'ChainAccount',
86
- { account: ChainAccountI, connectionHandler: ConnectionHandlerI },
87
- /**
88
- * @param {Port} port
89
- * @param {string} requestedRemoteAddress
90
- */
91
- (port, requestedRemoteAddress) =>
92
- /**
93
- * @type {{
94
- * port: Port;
95
- * connection: Remote<Connection> | undefined;
96
- * localAddress: string | undefined;
97
- * requestedRemoteAddress: string;
98
- * remoteAddress: string | undefined;
99
- * accountAddress: string | undefined;
100
- * }}
101
- */ (
102
- harden({
103
- port,
104
- connection: undefined,
105
- requestedRemoteAddress,
106
- remoteAddress: undefined,
107
- accountAddress: undefined,
108
- localAddress: undefined,
109
- })
110
- ),
111
- {
112
- account: {
113
- /**
114
- * @returns {string} the address of the account on the chain
115
- */
116
- getAccountAddress() {
117
- return NonNullish(
118
- this.state.accountAddress,
119
- 'Error parsing account address from remote address',
120
- );
121
- },
122
- getLocalAddress() {
123
- return NonNullish(
124
- this.state.localAddress,
125
- 'local address not available',
126
- );
127
- },
128
- getRemoteAddress() {
129
- return NonNullish(
130
- this.state.remoteAddress,
131
- 'remote address not available',
132
- );
133
- },
134
- getPort() {
135
- return this.state.port;
136
- },
137
- executeTx() {
138
- throw new Error('not yet implemented');
139
- },
140
- /**
141
- * Submit a transaction on behalf of the remote account for execution on the remote chain.
142
- * @param {AnyJson[]} msgs
143
- * @param {Omit<TxBody, 'messages'>} [opts]
144
- * @returns {Promise<string>} - base64 encoded bytes string. Can be decoded using the corresponding `Msg*Response` object.
145
- * @throws {Error} if packet fails to send or an error is returned
146
- */
147
- executeEncodedTx(msgs, opts) {
148
- const { connection } = this.state;
149
- if (!connection) throw Fail`connection not available`;
150
- return E.when(
151
- E(connection).send(makeTxPacket(msgs, opts)),
152
- // if parsePacketAck cannot find a `result` key, it throws
153
- ack => parsePacketAck(ack),
154
- );
155
- },
156
- /**
157
- * Close the remote account
158
- */
159
- async close() {
160
- /// XXX what should the behavior be here? and `onClose`?
161
- // - retrieve assets?
162
- // - revoke the port?
163
- const { connection } = this.state;
164
- if (!connection) throw Fail`connection not available`;
165
- await E(connection).close();
166
- },
167
- async deposit(payment) {
168
- console.log('deposit got', payment);
169
- throw new Error('not yet implemented');
170
- },
171
- /**
172
- * get Purse for a brand to .withdraw() a Payment from the account
173
- * @param {Brand} brand
174
- */
175
- async getPurse(brand) {
176
- console.log('getPurse got', brand);
177
- throw new Error('not yet implemented');
178
- },
179
-
180
- /* transfer account to new holder */
181
- async prepareTransfer() {
182
- throw new Error('not yet implemented');
183
- },
184
- },
185
- connectionHandler: {
186
- /**
187
- * @param {Remote<Connection>} connection
188
- * @param {string} localAddr
189
- * @param {string} remoteAddr
190
- */
191
- async onOpen(connection, localAddr, remoteAddr) {
192
- trace(`ICA Channel Opened for ${localAddr} at ${remoteAddr}`);
193
- this.state.connection = connection;
194
- this.state.remoteAddress = remoteAddr;
195
- this.state.localAddress = localAddr;
196
- // XXX parseAddress currently throws, should it return '' instead?
197
- this.state.accountAddress = parseAddress(remoteAddr);
198
- },
199
- async onClose(_connection, reason) {
200
- trace(`ICA Channel closed. Reason: ${reason}`);
201
- // XXX handle connection closing
202
- // XXX is there a scenario where a connection will unexpectedly close? _I think yes_
203
- },
204
- async onReceive(connection, bytes) {
205
- trace(`ICA Channel onReceive`, connection, bytes);
206
- return '';
207
- },
208
- },
209
- },
210
- );
211
-
212
47
  export const OrchestrationI = M.interface('Orchestration', {
213
- createAccount: M.callWhen(M.string(), M.string()).returns(
48
+ makeAccount: M.callWhen(M.string(), M.string()).returns(
214
49
  M.remotable('ChainAccount'),
215
50
  ),
216
51
  });
217
52
 
218
53
  /**
219
54
  * @param {Zone} zone
220
- * @param {ReturnType<typeof prepareChainAccount>} createChainAccount
55
+ * @param {ReturnType<typeof prepareChainAccountKit>} makeChainAccountKit
221
56
  */
222
- const prepareOrchestration = (zone, createChainAccount) =>
57
+ const prepareOrchestration = (zone, makeChainAccountKit) =>
223
58
  zone.exoClassKit(
224
59
  'Orchestration',
225
60
  {
@@ -254,20 +89,23 @@ const prepareOrchestration = (zone, createChainAccount) =>
254
89
  * self connection_id
255
90
  * @returns {Promise<ChainAccount>}
256
91
  */
257
- async createAccount(hostConnectionId, controllerConnectionId) {
92
+ async makeAccount(hostConnectionId, controllerConnectionId) {
258
93
  const port = await this.facets.self.bindPort();
259
94
 
260
95
  const remoteConnAddr = makeICAConnectionAddress(
261
96
  hostConnectionId,
262
97
  controllerConnectionId,
263
98
  );
264
- const chainAccount = createChainAccount(port, remoteConnAddr);
99
+ const chainAccountKit = makeChainAccountKit(port, remoteConnAddr);
265
100
 
266
101
  // await so we do not return a ChainAccount before it successfully instantiates
267
- await E(port).connect(remoteConnAddr, chainAccount.connectionHandler);
102
+ await E(port).connect(
103
+ remoteConnAddr,
104
+ chainAccountKit.connectionHandler,
105
+ );
268
106
  // XXX if we fail, should we close the port (if it was created in this flow)?
269
107
 
270
- return chainAccount.account;
108
+ return chainAccountKit.account;
271
109
  },
272
110
  },
273
111
  },
@@ -275,14 +113,13 @@ const prepareOrchestration = (zone, createChainAccount) =>
275
113
 
276
114
  /** @param {Zone} zone */
277
115
  export const prepareOrchestrationTools = zone => {
278
- const createChainAccount = prepareChainAccount(zone);
279
- const makeOrchestration = prepareOrchestration(zone, createChainAccount);
116
+ const makeChainAccountKit = prepareChainAccountKit(zone);
117
+ const makeOrchestration = prepareOrchestration(zone, makeChainAccountKit);
280
118
 
281
119
  return harden({ makeOrchestration });
282
120
  };
283
121
  harden(prepareOrchestrationTools);
284
122
 
285
- /** @typedef {ReturnType<ReturnType<typeof prepareChainAccount>>} ChainAccountKit */
286
123
  /** @typedef {ReturnType<typeof prepareOrchestrationTools>} OrchestrationTools */
287
124
  /** @typedef {ReturnType<OrchestrationTools['makeOrchestration']>} OrchestrationKit */
288
125
  /** @typedef {OrchestrationKit['public']} OrchestrationService */
package/src/types.d.ts CHANGED
@@ -4,7 +4,7 @@ import type { Invitation } from '@agoric/zoe/exported.js';
4
4
  import type { Any } from '@agoric/cosmic-proto/google/protobuf/any';
5
5
  import type { AnyJson } from '@agoric/cosmic-proto';
6
6
  import type {
7
- MsgCancelUnbondingDelegation,
7
+ MsgBeginRedelegateResponse,
8
8
  MsgUndelegateResponse,
9
9
  } from '@agoric/cosmic-proto/cosmos/staking/v1beta1/tx.js';
10
10
  import type {
@@ -12,6 +12,13 @@ import type {
12
12
  Redelegation,
13
13
  UnbondingDelegation,
14
14
  } from '@agoric/cosmic-proto/cosmos/staking/v1beta1/staking.js';
15
+ import type { TxBody } from '@agoric/cosmic-proto/cosmos/tx/v1beta1/tx.js';
16
+ import type {
17
+ LocalIbcAddress,
18
+ RemoteIbcAddress,
19
+ } from '@agoric/vats/tools/ibc-utils.js';
20
+ import type { Port } from '@agoric/network';
21
+ import { MsgTransferResponse } from '@agoric/cosmic-proto/ibc/applications/transfer/v1/tx.js';
15
22
 
16
23
  /**
17
24
  * static declaration of known chain types will allow type support for
@@ -203,7 +210,7 @@ export interface Chain<C extends keyof KnownChains> {
203
210
  * Creates a new account on the remote chain.
204
211
  * @returns an object that controls a new remote account on Chain
205
212
  */
206
- createAccount: () => Promise<OrchestrationAccount<C>>;
213
+ makeAccount: () => Promise<OrchestrationAccount<C>>;
207
214
  // FUTURE supply optional port object; also fetch port object
208
215
 
209
216
  /**
@@ -230,7 +237,7 @@ export interface ChainAccount {
230
237
  /**
231
238
  * @returns the address of the account on the remote chain
232
239
  */
233
- getAccountAddress: () => string;
240
+ getAddress: () => ChainAddress;
234
241
  /**
235
242
  * Submit a transaction on behalf of the remote account for execution on the remote chain.
236
243
  * @param msgs - records for the transaction
@@ -239,10 +246,14 @@ export interface ChainAccount {
239
246
  executeTx: (msgs: Proto3JSONMsg[]) => Promise<string>;
240
247
  /**
241
248
  * Submit a transaction on behalf of the remote account for execution on the remote chain.
242
- * @param msgs - records for the transaction
243
- * @returns acknowledge string
249
+ * @param {AnyJson[]} msgs - records for the transaction
250
+ * @param {Partial<Omit<TxBody, 'messages'>>} [opts] - optional parameters for the Tx, like `timeoutHeight` and `memo`
251
+ * @returns acknowledgement string
244
252
  */
245
- executeEncodedTx: (msgs: AnyJson[]) => Promise<string>;
253
+ executeEncodedTx: (
254
+ msgs: AnyJson[],
255
+ opts?: Partial<Omit<TxBody, 'messages'>>,
256
+ ) => Promise<string>;
246
257
  /** deposit payment from zoe to the account*/
247
258
  deposit: (payment: Payment) => Promise<void>;
248
259
  /** get Purse for a brand to .withdraw() a Payment from the account */
@@ -253,16 +264,12 @@ export interface ChainAccount {
253
264
  close: () => Promise<void>;
254
265
  /* transfer account to new holder */
255
266
  prepareTransfer: () => Promise<Invitation>;
256
- }
257
-
258
- export interface Undelegation {
259
- cancel: () => Promise<MsgCancelUnbondingDelegation>;
260
- response: MsgUndelegateResponse;
261
- /**
262
- * Resolves when the undelegation is complete and the tokens are no longer bonded.
263
- * Note it may take weeks.
264
- */
265
- completion: Promise<void>;
267
+ /** @returns the address of the remote channel */
268
+ getRemoteAddress: () => RemoteIbcAddress;
269
+ /** @returns the address of the local channel */
270
+ getLocalAddress: () => LocalIbcAddress;
271
+ /** @returns the port the ICA channel is bound to */
272
+ getPort: () => Port;
266
273
  }
267
274
 
268
275
  /**
@@ -275,7 +282,7 @@ export interface BaseOrchestrationAccount {
275
282
  /**
276
283
  * @returns the address of the account on the remote chain
277
284
  */
278
- getChainAddress: () => ChainAddress;
285
+ getAddress: () => ChainAddress;
279
286
 
280
287
  /** @returns an array of amounts for every balance in the account. */
281
288
  getBalances: () => Promise<ChainAmount[]>;
@@ -361,13 +368,14 @@ export interface BaseOrchestrationAccount {
361
368
  srcValidator: CosmosValidatorAddress,
362
369
  dstValidator: CosmosValidatorAddress,
363
370
  amount: AmountArg,
364
- ) => Promise<void>;
371
+ ) => Promise<MsgBeginRedelegateResponse>;
365
372
 
366
373
  /**
367
374
  * Undelegate multiple delegations (concurrently). To delegate independently, pass an array with one item.
368
- * @param delegations - the delegation to undelegate
375
+ * Resolves when the undelegation is complete and the tokens are no longer bonded. Note it may take weeks.
376
+ * @param {Delegation[]} delegations - the delegation to undelegate
369
377
  */
370
- undelegate: (delegations: Delegation[]) => Promise<Undelegation[]>;
378
+ undelegate: (delegations: Delegation[]) => Promise<MsgUndelegateResponse>;
371
379
 
372
380
  /**
373
381
  * Withdraw rewards from all validators. The promise settles when the rewards are withdrawn.
@@ -396,7 +404,7 @@ export interface BaseOrchestrationAccount {
396
404
  amount: AmountArg,
397
405
  destination: ChainAddress,
398
406
  memo?: string,
399
- ) => Promise<void>;
407
+ ) => Promise<MsgTransferResponse>;
400
408
 
401
409
  /**
402
410
  * Transfer an amount to another account in multiple steps. The promise settles when
@@ -405,7 +413,10 @@ export interface BaseOrchestrationAccount {
405
413
  * @param msg - the transfer message, including follow-up steps
406
414
  * @returns void
407
415
  */
408
- transferSteps: (amount: AmountArg, msg: TransferMsg) => Promise<void>;
416
+ transferSteps: (
417
+ amount: AmountArg,
418
+ msg: TransferMsg,
419
+ ) => Promise<MsgTransferResponse>;
409
420
  /**
410
421
  * deposit payment from zoe to the account. For remote accounts,
411
422
  * an IBC Transfer will be executed to transfer funds there.
@@ -428,12 +439,11 @@ export type TransferMsg = {
428
439
  data?: object;
429
440
  };
430
441
 
431
- // Example
432
- // await icaNoble.transferSteps(usdcAmt,
433
- // osmosisSwap(tiaBrand, { pool: 1224, slippage: 0.05 }, icaCel.getAddress()));
434
-
435
442
  /**
436
443
  * @param pool - Required. Pool number
444
+ * @example
445
+ * await icaNoble.transferSteps(usdcAmt,
446
+ * osmosisSwap(tiaBrand, { pool: 1224, slippage: 0.05 }, icaCel.getAddress()));
437
447
  */
438
448
  export type OsmoSwapOptions = {
439
449
  pool: string;
@@ -452,6 +462,10 @@ export type OsmoSwapFn = (
452
462
  next: TransferMsg | ChainAddress,
453
463
  ) => TransferMsg;
454
464
 
455
- type AfterAction = { destChain: string; destAddress: ChainAddress };
456
- type SwapExact = { amountIn: Amount; amountOut: Amount };
457
- type SwapMaxSlippage = { amountIn: Amount; brandOut: Brand; slippage: number };
465
+ export type AfterAction = { destChain: string; destAddress: ChainAddress };
466
+ export type SwapExact = { amountIn: Amount; amountOut: Amount };
467
+ export type SwapMaxSlippage = {
468
+ amountIn: Amount;
469
+ brandOut: Brand;
470
+ slippage: number;
471
+ };