@agoric/orchestration 0.1.1-dev-27cc9b8.0 → 0.1.1-dev-96c19f5.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.
Files changed (33) hide show
  1. package/package.json +15 -15
  2. package/src/chain-info.d.ts.map +1 -1
  3. package/src/chain-info.js +8 -16
  4. package/src/examples/sendAnywhere.contract.d.ts +74 -0
  5. package/src/examples/sendAnywhere.contract.d.ts.map +1 -0
  6. package/src/examples/sendAnywhere.contract.js +168 -0
  7. package/src/examples/stakeBld.contract.d.ts +0 -2
  8. package/src/examples/stakeBld.contract.d.ts.map +1 -1
  9. package/src/examples/stakeBld.contract.js +3 -11
  10. package/src/examples/swapExample.contract.d.ts +1 -0
  11. package/src/examples/swapExample.contract.d.ts.map +1 -1
  12. package/src/examples/swapExample.contract.js +18 -1
  13. package/src/examples/unbondExample.contract.d.ts +3 -1
  14. package/src/examples/unbondExample.contract.d.ts.map +1 -1
  15. package/src/examples/unbondExample.contract.js +16 -1
  16. package/src/exos/local-chain-account-kit.d.ts +11 -35
  17. package/src/exos/local-chain-account-kit.d.ts.map +1 -1
  18. package/src/exos/local-chain-account-kit.js +15 -18
  19. package/src/facade.d.ts +3 -19
  20. package/src/facade.d.ts.map +1 -1
  21. package/src/facade.js +22 -52
  22. package/src/proposals/start-stakeBld.d.ts +0 -1
  23. package/src/proposals/start-stakeBld.d.ts.map +1 -1
  24. package/src/proposals/start-stakeBld.js +1 -3
  25. package/src/typeGuards.d.ts +4 -0
  26. package/src/typeGuards.d.ts.map +1 -1
  27. package/src/typeGuards.js +31 -1
  28. package/src/utils/chainHub.d.ts +51 -0
  29. package/src/utils/chainHub.d.ts.map +1 -0
  30. package/src/utils/chainHub.js +136 -0
  31. package/src/utils/time.d.ts +4 -7
  32. package/src/utils/time.d.ts.map +1 -1
  33. package/src/utils/time.js +15 -7
@@ -20,7 +20,9 @@ import { dateInSeconds, makeTimestampHelper } from '../utils/time.js';
20
20
  * @import {AmountArg, ChainAddress, DenomAmount, IBCMsgTransferOptions, CosmosChainInfo} from '@agoric/orchestration';
21
21
  * @import {RecorderKit, MakeRecorderKit} from '@agoric/zoe/src/contractSupport/recorder.js'.
22
22
  * @import {Zone} from '@agoric/zone';
23
+ * @import {Remote} from '@agoric/internal';
23
24
  * @import {TimerService, TimerBrand} from '@agoric/time';
25
+ * @import {ChainHub} from '../utils/chainHub.js';
24
26
  */
25
27
 
26
28
  const trace = makeTracer('LCAH');
@@ -43,7 +45,7 @@ const HolderI = M.interface('holder', {
43
45
  getPublicTopics: M.call().returns(TopicsRecordShape),
44
46
  delegate: M.call(M.string(), AmountShape).returns(M.promise()),
45
47
  undelegate: M.call(M.string(), AmountShape).returns(M.promise()),
46
- deposit: M.callWhen(PaymentShape).returns(AmountShape),
48
+ deposit: M.callWhen(PaymentShape).optional(AmountShape).returns(AmountShape),
47
49
  withdraw: M.callWhen(AmountShape).returns(PaymentShape),
48
50
  transfer: M.call(AmountArgShape, ChainAddressShape)
49
51
  .optional(IBCTransferOptionsShape)
@@ -61,22 +63,19 @@ const PUBLIC_TOPICS = {
61
63
  * @param {Zone} zone
62
64
  * @param {MakeRecorderKit} makeRecorderKit
63
65
  * @param {ZCF} zcf
64
- * @param {TimerService} timerService
65
- * @param {TimerBrand} timerBrand
66
- * @param {CosmosChainInfo} agoricChainInfo
66
+ * @param {Remote<TimerService>} timerService
67
+ * @param {ChainHub} chainHub
67
68
  */
68
69
  export const prepareLocalChainAccountKit = (
69
70
  zone,
70
71
  makeRecorderKit,
71
72
  zcf,
72
73
  timerService,
73
- timerBrand,
74
- agoricChainInfo,
74
+ chainHub,
75
75
  ) => {
76
- const timestampHelper = makeTimestampHelper(timerService, timerBrand);
77
- /**
78
- * Make an object wrapping an LCA with Zoe interfaces.
79
- */
76
+ const timestampHelper = makeTimestampHelper(timerService);
77
+ // TODO: rename to makeLocalOrchestrationAccount or the like to distinguish from lca
78
+ /** Make an object wrapping an LCA with Zoe interfaces. */
80
79
  const makeLocalChainAccountKit = zone.exoClassKit(
81
80
  'LCA Kit',
82
81
  {
@@ -220,9 +219,7 @@ export const prepareLocalChainAccountKit = (
220
219
  // @ts-expect-error subtype
221
220
  return E(this.state.account).executeTx(messages);
222
221
  },
223
- /**
224
- * @returns {ChainAddress['address']}
225
- */
222
+ /** @returns {ChainAddress['address']} */
226
223
  getAddress() {
227
224
  return NonNullish(this.state.address, 'Chain address not available.');
228
225
  },
@@ -240,12 +237,12 @@ export const prepareLocalChainAccountKit = (
240
237
  // TODO #9211 lookup denom from brand
241
238
  if ('brand' in amount) throw Fail`ERTP Amounts not yet supported`;
242
239
 
243
- destination.chainId in agoricChainInfo.connections ||
244
- Fail`Unknown chain ${destination.chainId}`;
245
-
246
240
  // TODO #8879 chainInfo and #9063 well-known chains
247
- const { transferChannel } =
248
- agoricChainInfo.connections[destination.chainId];
241
+ const agoricChainInfo = await chainHub.getChainInfo('agoric');
242
+ const { transferChannel } = await chainHub.getConnectionInfo(
243
+ agoricChainInfo.chainId,
244
+ destination.chainId,
245
+ );
249
246
 
250
247
  await null;
251
248
  // set a `timeoutTimestamp` if caller does not supply either `timeoutHeight` or `timeoutTimestamp`
package/src/facade.d.ts CHANGED
@@ -1,6 +1,4 @@
1
- /** agoricNames key for ChainInfo hub */
2
- export const CHAIN_KEY: "chain";
3
- export function makeOrchestrationFacade({ zone, timerService, zcf, storageNode, orchestrationService, localchain, agoricNames, }: {
1
+ export function makeOrchestrationFacade({ zone, timerService, zcf, storageNode, orchestrationService, localchain, chainHub, makeLocalChainAccountKit, }: {
4
2
  zone: Zone;
5
3
  timerService: Remote<TimerService>;
6
4
  zcf: ZCF;
@@ -34,21 +32,9 @@ export function makeOrchestrationFacade({ zone, timerService, zcf, storageNode,
34
32
  };
35
33
  }[]>;
36
34
  }>>;
37
- agoricNames: Remote<NameHub>;
35
+ chainHub: import("./utils/chainHub.js").ChainHub;
36
+ makeLocalChainAccountKit: ReturnType<typeof import("./exos/local-chain-account-kit.js").prepareLocalChainAccountKit>;
38
37
  }): {
39
- /**
40
- * Register a new chain in a heap store. The name will override a name in
41
- * well known chain names.
42
- *
43
- * This registration will not surve a reincarnation of the vat so if the
44
- * chain is not yet in the well known names at that point, it will have to
45
- * be registered again. In an unchanged contract `start` the call will
46
- * happen again naturally.
47
- *
48
- * @param {string} name
49
- * @param {ChainInfo} chainInfo
50
- */
51
- registerChain(name: string, chainInfo: ChainInfo): void;
52
38
  /**
53
39
  * @template Context
54
40
  * @template {any[]} Args
@@ -64,7 +50,5 @@ export type OrchestrationFacade = ReturnType<typeof makeOrchestrationFacade>;
64
50
  import type { Zone } from '@agoric/zone';
65
51
  import type { TimerService } from '@agoric/time';
66
52
  import type { Remote } from '@agoric/internal';
67
- import type { NameHub } from '@agoric/vats';
68
- import type { ChainInfo } from './types.js';
69
53
  import type { Orchestrator } from './types.js';
70
54
  //# sourceMappingURL=facade.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"facade.d.ts","sourceRoot":"","sources":["facade.js"],"names":[],"mappings":"AAsBA,wCAAwC;AACxC,gCAAiC;AA2I1B;;;SAPG,GAAG;;;;;;;;;;;;;8BAlG6B,MAAM,KAC9C,CAAC;6BAYW,QAAO,KAAK,CAAC,mBAEX,OAAO;6BAeV,OAAO,KAAK,CAAC;;;2BAyBf,EAAE;;;uBA6F6B,OAAO,sBAAsB,EAAE,SACpE;;;4BAiBA,OAAG,sBAAsB,EAAG,SAAQ,EAAE;;;;;;;;;IAtBvC;;;;;;;;;;;OAWG;wBAFQ,MAAM;IAMjB;;;;;;;;OAQG;gBAFkC,OAAO,EACrB,IAAI,6BAJhB,MAAM,OAGoB,OAAO,AAD1B,gCACmB,OAAO,WACrB,IAAI,AADgC,KAAK,MAAM,GACzD,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,OAAO,CAAC;EA4BnD;kCAEa,UAAU,CAAC,OAAO,uBAAuB,CAAC;0BAnPjC,cAAc;kCACN,cAAc;4BAEpB,kBAAkB;6BAJjB,cAAc;+BAMgD,YAAY;kCAAZ,YAAY"}
1
+ {"version":3,"file":"facade.d.ts","sourceRoot":"","sources":["facade.js"],"names":[],"mappings":"AAuKO;;;SAVG,GAAG;;;;;;;;;;;;;8BArGY,MAAM,KAAK,CAAC;6BAczB,QAAQ,KAAK,CAAC,mBACZ,OAAK;6BAc0C,OACnD,KAAH,CAAC;;;2BAuBJ,EAAE;;;uBAsFgB,OAAO,sBAClB,EAAE,SAAS;;;4BA0BV,OAAO,sBACX,EAAE,SAAS,EAAE;;;;;;;cA9DN,OAAO,qBAAqB,EAAE,QAAQ;8BACtB,UAAU,CACxC,cAAoB,mCAAmC,EAAE,2BAA2B,CAC/E;;IAsBF;;;;;;;;OAQG;gBAFkC,OAAO,EACrB,IAAI,6BAJhB,MAAM,OAGoB,OAAO,AAD1B,gCACmB,OAAO,WACrB,IAAI,AADgC,KAAK,MAAM,GACzD,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,OAAO,CAAC;EA4BnD;kCAEa,UAAU,CAAC,OAAO,uBAAuB,CAAC;0BAzNjC,cAAc;kCACN,cAAc;4BAEpB,kBAAkB;kCAE6C,YAAY"}
package/src/facade.js CHANGED
@@ -1,13 +1,9 @@
1
1
  /** @file Orchestration service */
2
2
 
3
- import { makeScalarBigMapStore } from '@agoric/vat-data';
4
3
  import { E } from '@endo/far';
5
- import { M } from '@endo/patterns';
6
4
  import { prepareCosmosOrchestrationAccount } from './exos/cosmosOrchestrationAccount.js';
7
- import { CosmosChainInfoShape } from './typeGuards.js';
8
5
 
9
6
  /**
10
- * @import {NameHub} from '@agoric/vats';
11
7
  * @import {Zone} from '@agoric/zone';
12
8
  * @import {TimerService} from '@agoric/time';
13
9
  * @import {LocalChain} from '@agoric/vats/src/localchain.js';
@@ -19,10 +15,6 @@ import { CosmosChainInfoShape } from './typeGuards.js';
19
15
  /** @type {any} */
20
16
  const anyVal = null;
21
17
 
22
- // TODO define key hierarchy in shared constants
23
- /** agoricNames key for ChainInfo hub */
24
- export const CHAIN_KEY = 'chain';
25
-
26
18
  // FIXME look up real values
27
19
  // UNTIL https://github.com/Agoric/agoric-sdk/issues/9063
28
20
  const mockLocalChainInfo = {
@@ -37,9 +29,12 @@ const mockLocalChainInfo = {
37
29
 
38
30
  /**
39
31
  * @param {Remote<LocalChain>} localchain
32
+ * @param {ReturnType<
33
+ * typeof import('./exos/local-chain-account-kit.js').prepareLocalChainAccountKit
34
+ * >} makeLocalChainAccountKit
40
35
  * @returns {Chain}
41
36
  */
42
- const makeLocalChainFacade = localchain => {
37
+ const makeLocalChainFacade = (localchain, makeLocalChainAccountKit) => {
43
38
  return {
44
39
  /** @returns {Promise<ChainInfo>} */
45
40
  async getChainInfo() {
@@ -47,7 +42,14 @@ const makeLocalChainFacade = localchain => {
47
42
  },
48
43
 
49
44
  async makeAccount() {
50
- const account = await E(localchain).makeAccount();
45
+ const lcaP = E(localchain).makeAccount();
46
+ const [lca, address] = await Promise.all([lcaP, E(lcaP).getAddress()]);
47
+ const { holder: account } = makeLocalChainAccountKit({
48
+ account: lca,
49
+ address,
50
+ // @ts-expect-error TODO: Remote
51
+ storageNode: null,
52
+ });
51
53
 
52
54
  return {
53
55
  async deposit(payment) {
@@ -70,7 +72,7 @@ const makeLocalChainFacade = localchain => {
70
72
  ? [/** @type {any} */ (null), denomArg]
71
73
  : [denomArg, 'FIXME'];
72
74
 
73
- const natAmount = await account.getBalance(brand);
75
+ const natAmount = await E(lca).getBalance(brand);
74
76
  return harden({ denom, value: natAmount.value });
75
77
  },
76
78
  getBalances() {
@@ -81,8 +83,8 @@ const makeLocalChainFacade = localchain => {
81
83
  console.log('send got', toAccount, amount);
82
84
  },
83
85
  async transfer(amount, destination, opts) {
84
- // FIXME implement
85
86
  console.log('transfer got', amount, destination, opts);
87
+ return account.transfer(amount, destination, opts);
86
88
  },
87
89
  transferSteps(amount, msg) {
88
90
  console.log('transferSteps got', amount, msg);
@@ -157,7 +159,10 @@ const makeRemoteChainFacade = (
157
159
  * storageNode: Remote<StorageNode>;
158
160
  * orchestrationService: Remote<OrchestrationService>;
159
161
  * localchain: Remote<LocalChain>;
160
- * agoricNames: Remote<NameHub>;
162
+ * chainHub: import('./utils/chainHub.js').ChainHub;
163
+ * makeLocalChainAccountKit: ReturnType<
164
+ * typeof import('./exos/local-chain-account-kit.js').prepareLocalChainAccountKit
165
+ * >;
161
166
  * }} powers
162
167
  */
163
168
  export const makeOrchestrationFacade = ({
@@ -167,7 +172,8 @@ export const makeOrchestrationFacade = ({
167
172
  storageNode,
168
173
  orchestrationService,
169
174
  localchain,
170
- agoricNames,
175
+ chainHub,
176
+ makeLocalChainAccountKit,
171
177
  }) => {
172
178
  console.log('makeOrchestrationFacade got', {
173
179
  zone,
@@ -177,43 +183,7 @@ export const makeOrchestrationFacade = ({
177
183
  orchestrationService,
178
184
  });
179
185
 
180
- const chainInfos = makeScalarBigMapStore('chainInfos', {
181
- keyShape: M.string(),
182
- valueShape: CosmosChainInfoShape,
183
- });
184
-
185
- /**
186
- * @param {string} name
187
- * @returns {Promise<CosmosChainInfo>}
188
- */
189
- const getChainInfo = async name => {
190
- // Either from registerChain or memoized remote lookup()
191
- if (chainInfos.has(name)) {
192
- return chainInfos.get(name);
193
- }
194
-
195
- const chainInfo = await E(agoricNames).lookup(CHAIN_KEY, name);
196
- assert(chainInfo, `unknown chain ${name}`);
197
- chainInfos.init(name, chainInfo);
198
- return chainInfo;
199
- };
200
-
201
186
  return {
202
- /**
203
- * Register a new chain in a heap store. The name will override a name in
204
- * well known chain names.
205
- *
206
- * This registration will not surve a reincarnation of the vat so if the
207
- * chain is not yet in the well known names at that point, it will have to
208
- * be registered again. In an unchanged contract `start` the call will
209
- * happen again naturally.
210
- *
211
- * @param {string} name
212
- * @param {ChainInfo} chainInfo
213
- */
214
- registerChain(name, chainInfo) {
215
- chainInfos.init(name, chainInfo);
216
- },
217
187
  /**
218
188
  * @template Context
219
189
  * @template {any[]} Args
@@ -228,10 +198,10 @@ export const makeOrchestrationFacade = ({
228
198
  const orc = {
229
199
  async getChain(name) {
230
200
  if (name === 'agoric') {
231
- return makeLocalChainFacade(localchain);
201
+ return makeLocalChainFacade(localchain, makeLocalChainAccountKit);
232
202
  }
233
203
 
234
- const chainInfo = await getChainInfo(name);
204
+ const chainInfo = await chainHub.getChainInfo(name);
235
205
 
236
206
  return makeRemoteChainFacade(chainInfo, {
237
207
  orchestration: orchestrationService,
@@ -32,7 +32,6 @@ export function startStakeBld({ consume: { agoricNames: agoricNamesP, agoricName
32
32
  };
33
33
  storageNode: globalThis.StorageNode;
34
34
  timerService: import("@agoric/time").TimerService;
35
- timerBrand: import("@agoric/time").TimerBrand;
36
35
  }, baggage: import("@agoric/vat-data").Baggage) => Promise<{
37
36
  publicFacet: import("@endo/exo").Guarded<{
38
37
  makeStakeBldInvitation(): Promise<Invitation<{
@@ -1 +1 @@
1
- {"version":3,"file":"start-stakeBld.d.ts","sourceRoot":"","sources":["start-stakeBld.js"],"names":[],"mappings":"AAmBO,+UAVI,eAAe,GAAG;IAC5B,YAAgB,EAAE;QAClB,OAAa,EAAE;YACf,QAAgB,EAAE,YAAY,OAqBX,GAAG;;;;;0CA6BF,MACjB,KAAK,CAAC;yCAiBK,QAEf,KAAI,CAAC,mBAA2B,OAAO;yCAoBF,OAC7B,KAAJ,CAAC;;;uCAQ+a,EAAE;;;mCAAg0E,OAAO,sBAAsB,EAAE,SAAS;;;wCAAyqB,OAAO,sBAAsB,EAAE,SAAS,EAAE;;;;;;;;;;;;;;;;wBApEz+G,OAAO,kBAAkB,EAAE,OAAO;;;;;;;;;;;2EAoEw2B,OAAO,KAAK,CAAC;;;6EAAid,OAAO,KAAK,CAAC;;;;;;;;;;;2EAAs4B,OAAO,KAAK,CAAC;;;6EAA+yB,OAAO,KAAK,CAAC;6CA/B7jG,QAEf,KAAI,CAAC,mBAA2B,OAAO;6CAoBF,OAC7B,KAAJ,CAAC;;;2CAQ+a,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAjG5a,CAAC;SACH,CAAC;KACH,CAAC;CACH,iBA8DH;AAGM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BN;sBA5GqB,gCAAgC"}
1
+ {"version":3,"file":"start-stakeBld.d.ts","sourceRoot":"","sources":["start-stakeBld.js"],"names":[],"mappings":"AAmBO,+UAVI,eAAe,GAAG;IAC5B,YAAgB,EAAE;QAClB,OAAa,EAAE;YACf,QAAgB,EAAE,YAAY,OAwB3B,GAAD;;;;;0CA2BqC,MAAM,KAAK,CAAC;yCAkBlD,QACE,KAAA,CAAC,mBACW,OAAO;yCAsBS,OAAO,KAAK,CAAC;;;uCAI+d,EAAE;;;mCAAg0E,OAAO,sBAAsB,EAAE,SAAS;;;wCAAyqB,OAAO,sBAAsB,EAAE,SAAS,EAAE;;;;;;;;;;;;;;;wBAlErjH,OAAO,kBAAkB,EAAE,OAAO;;;;;;;;;;;2EAkEgjC,OAAO,KAAK,CAAC;;;6EAAid,OAAO,KAAK,CAAC;;;;;;;;;;;2EAAs4B,OAAO,KAAK,CAAC;;;6EAA+yB,OAAO,KAAK,CAAC;6CA5B9xG,QACE,KAAA,CAAC,mBACW,OAAO;6CAsBS,OAAO,KAAK,CAAC;;;2CAI+d,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eA/FpgB,CAAC;SACH,CAAC;KACH,CAAC;CACH,iBA4DH;AAGM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BN;sBA1GqB,gCAAgC"}
@@ -48,10 +48,9 @@ export const startStakeBld = async ({
48
48
  // NB: committee must only publish what it intended to be public
49
49
  const marshaller = await E(board).getPublishingMarshaller();
50
50
 
51
- const [agoricNames, timerService, timerBrand] = await Promise.all([
51
+ const [agoricNames, timerService] = await Promise.all([
52
52
  agoricNamesP,
53
53
  chainTimerServiceP,
54
- chainTimerServiceP.then(ts => E(ts).getTimerBrand()),
55
54
  ]);
56
55
 
57
56
  /**
@@ -69,7 +68,6 @@ export const startStakeBld = async ({
69
68
  agoricNames,
70
69
  localchain: await localchain,
71
70
  timerService,
72
- timerBrand,
73
71
  storageNode,
74
72
  marshaller,
75
73
  },
@@ -30,5 +30,9 @@ export namespace DelegationShape {
30
30
  let shares: import("@endo/patterns").Matcher;
31
31
  }
32
32
  export const IBCTransferOptionsShape: import("@endo/patterns").Matcher;
33
+ export const IBCChannelIDShape: import("@endo/patterns").Matcher;
34
+ export const IBCChannelInfoShape: import("@endo/patterns").Matcher;
35
+ export const IBCConnectionIDShape: import("@endo/patterns").Matcher;
36
+ export const IBCConnectionInfoShape: import("@endo/patterns").Matcher;
33
37
  export const CosmosChainInfoShape: import("@endo/patterns").Matcher;
34
38
  //# sourceMappingURL=typeGuards.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"typeGuards.d.ts","sourceRoot":"","sources":["typeGuards.js"],"names":[],"mappings":"AAGA;;;;GAIG;;;;;;;;;;;;;;;;;;;;;AAiBH,8DAAkE;;;;;;AAQlE,uEAUE;AAEF,oEAYE"}
1
+ {"version":3,"file":"typeGuards.d.ts","sourceRoot":"","sources":["typeGuards.js"],"names":[],"mappings":"AAGA;;;;GAIG;;;;;;;;;;;;;;;;;;;;;AAiBH,8DAAkE;;;;;;AAQlE,uEAUE;AAEF,iEAA4C;AAC5C,mEAQG;AACH,oEAA+C;AAC/C,sEAiBG;AAEH,oEAYE"}
package/src/typeGuards.js CHANGED
@@ -42,13 +42,43 @@ export const IBCTransferOptionsShape = M.splitRecord(
42
42
  },
43
43
  );
44
44
 
45
+ export const IBCChannelIDShape = M.string();
46
+ export const IBCChannelInfoShape = M.splitRecord({
47
+ portId: M.string(),
48
+ channelId: IBCChannelIDShape,
49
+ counterPartyPortId: M.string(),
50
+ counterPartyChannelId: IBCChannelIDShape,
51
+ ordering: M.scalar(), // XXX
52
+ state: M.scalar(), // XXX
53
+ version: M.string(),
54
+ });
55
+ export const IBCConnectionIDShape = M.string();
56
+ export const IBCConnectionInfoShape = M.splitRecord({
57
+ id: IBCConnectionIDShape,
58
+ client_id: M.string(),
59
+ state: M.scalar(), // XXX STATE_OPEN or...
60
+ counterparty: {
61
+ client_id: M.string(),
62
+ connection_id: IBCConnectionIDShape,
63
+ prefix: {
64
+ key_prefix: M.string(),
65
+ },
66
+ },
67
+ versions: M.arrayOf({
68
+ identifier: M.string(),
69
+ features: M.arrayOf(M.string()),
70
+ }),
71
+ delay_period: M.nat(),
72
+ transferChannel: IBCChannelInfoShape,
73
+ });
74
+
45
75
  export const CosmosChainInfoShape = M.splitRecord(
46
76
  {
47
77
  chainId: M.string(),
48
78
  connections: M.record(),
49
- stakingTokens: M.arrayOf({ denom: M.string() }),
50
79
  },
51
80
  {
81
+ stakingTokens: M.arrayOf({ denom: M.string() }),
52
82
  icaEnabled: M.boolean(),
53
83
  icqEnabled: M.boolean(),
54
84
  pfmEnabled: M.boolean(),
@@ -0,0 +1,51 @@
1
+ /**
2
+ * @import {NameHub} from '@agoric/vats';
3
+ * @import {CosmosChainInfo, IBCConnectionInfo} from '../cosmos-api.js';
4
+ * @import {Remote} from '@agoric/internal';
5
+ * @import {Zone} from '@agoric/zone';
6
+ */
7
+ /** agoricNames key for ChainInfo hub */
8
+ export const CHAIN_KEY: "chain";
9
+ /** namehub for connection info */
10
+ export const CONNECTIONS_KEY: "chainConnection";
11
+ export function connectionKey(chainId1: string, chainId2: string): string;
12
+ export function makeChainHub(agoricNames: Remote<NameHub>, zone?: Zone | undefined): {
13
+ /**
14
+ * Register a new chain. The name will override a name in well known chain
15
+ * names.
16
+ *
17
+ * If a durable zone was not provided, registration will not survive a
18
+ * reincarnation of the vat. Then if the chain is not yet in the well known
19
+ * names at that point, it will have to be registered again. In an unchanged
20
+ * contract `start` the call will happen again naturally.
21
+ *
22
+ * @param {string} name
23
+ * @param {CosmosChainInfo} chainInfo
24
+ */
25
+ registerChain(name: string, chainInfo: CosmosChainInfo): void;
26
+ /**
27
+ * @param {string} chainName
28
+ * @returns {Promise<CosmosChainInfo>}
29
+ */
30
+ getChainInfo(chainName: string): Promise<CosmosChainInfo>;
31
+ /**
32
+ * @param {string} srcChainId
33
+ * @param {string} destChainId
34
+ * @param {IBCConnectionInfo} connectionInfo
35
+ */
36
+ registerConnection(srcChainId: string, destChainId: string, connectionInfo: IBCConnectionInfo): void;
37
+ /**
38
+ * @param {string} srcChainId
39
+ * @param {string} destChainId
40
+ * @returns {Promise<IBCConnectionInfo>}
41
+ */
42
+ getConnectionInfo(srcChainId: string, destChainId: string): Promise<IBCConnectionInfo>;
43
+ };
44
+ export function registerChain(agoricNamesAdmin: ERef<import("@agoric/vats").NameHubKit["nameAdmin"]>, name: string, chainInfo: CosmosChainInfo): Promise<void>;
45
+ export type ChainHub = ReturnType<typeof makeChainHub>;
46
+ import type { NameHub } from '@agoric/vats';
47
+ import type { Remote } from '@agoric/internal';
48
+ import type { Zone } from '@agoric/zone';
49
+ import type { CosmosChainInfo } from '../cosmos-api.js';
50
+ import type { IBCConnectionInfo } from '../cosmos-api.js';
51
+ //# sourceMappingURL=chainHub.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chainHub.d.ts","sourceRoot":"","sources":["chainHub.js"],"names":[],"mappings":"AAKA;;;;;GAKG;AAEH,wCAAwC;AACxC,gCAAiC;AACjC,kCAAkC;AAClC,gDAAiD;AAU1C,wCAHI,MAAM,YACN,MAAM,UAG4B;AAMtC;IAaH;;;;;;;;;;;OAWG;wBAFQ,MAAM;IAMjB;;;OAGG;4BAFQ,MAAM;IAiBjB;;;;OAIG;mCAHQ,MAAM,eACN,MAAM;IAQjB;;;;OAIG;kCAHQ,MAAM,eACN,MAAM;EAsBpB;AAQM,gDAJI,IAAI,CAAC,OAAO,cAAc,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC,QACpD,MAAM,6CAkBhB;uBAtBa,UAAU,CAAC,OAAO,YAAY,CAAC;6BA3GnB,cAAc;4BAEf,kBAAkB;0BACpB,cAAc;qCAFgB,kBAAkB;uCAAlB,kBAAkB"}
@@ -0,0 +1,136 @@
1
+ import { E } from '@endo/far';
2
+ import { M, mustMatch } from '@endo/patterns';
3
+ import { makeHeapZone } from '@agoric/zone';
4
+ import { CosmosChainInfoShape, IBCConnectionInfoShape } from '../typeGuards.js';
5
+
6
+ /**
7
+ * @import {NameHub} from '@agoric/vats';
8
+ * @import {CosmosChainInfo, IBCConnectionInfo} from '../cosmos-api.js';
9
+ * @import {Remote} from '@agoric/internal';
10
+ * @import {Zone} from '@agoric/zone';
11
+ */
12
+
13
+ /** agoricNames key for ChainInfo hub */
14
+ export const CHAIN_KEY = 'chain';
15
+ /** namehub for connection info */
16
+ export const CONNECTIONS_KEY = 'chainConnection';
17
+
18
+ /**
19
+ * The entries of the top-level namehubs in agoricNames are reflected to
20
+ * vstorage. But only the top level. So we combine the 2 chain ids into 1 key.
21
+ * Connections are directionless, so we sort the ids.
22
+ *
23
+ * @param {string} chainId1
24
+ * @param {string} chainId2
25
+ */
26
+ export const connectionKey = (chainId1, chainId2) =>
27
+ JSON.stringify([chainId1, chainId2].sort());
28
+
29
+ /**
30
+ * @param {Remote<NameHub>} agoricNames
31
+ * @param {Zone} [zone]
32
+ */
33
+ export const makeChainHub = (agoricNames, zone = makeHeapZone()) => {
34
+ /** @type {MapStore<string, CosmosChainInfo>} */
35
+ const chainInfos = zone.mapStore('chainInfos', {
36
+ keyShape: M.string(),
37
+ valueShape: CosmosChainInfoShape,
38
+ });
39
+ /** @type {MapStore<string, IBCConnectionInfo>} */
40
+ const connectionInfos = zone.mapStore('connectionInfos', {
41
+ keyShape: M.string(),
42
+ valueShape: IBCConnectionInfoShape,
43
+ });
44
+
45
+ const chainHub = harden({
46
+ /**
47
+ * Register a new chain. The name will override a name in well known chain
48
+ * names.
49
+ *
50
+ * If a durable zone was not provided, registration will not survive a
51
+ * reincarnation of the vat. Then if the chain is not yet in the well known
52
+ * names at that point, it will have to be registered again. In an unchanged
53
+ * contract `start` the call will happen again naturally.
54
+ *
55
+ * @param {string} name
56
+ * @param {CosmosChainInfo} chainInfo
57
+ */
58
+ registerChain(name, chainInfo) {
59
+ chainInfos.init(name, chainInfo);
60
+ },
61
+ /**
62
+ * @param {string} chainName
63
+ * @returns {Promise<CosmosChainInfo>}
64
+ */
65
+ async getChainInfo(chainName) {
66
+ // Either from registerChain or memoized remote lookup()
67
+ if (chainInfos.has(chainName)) {
68
+ return chainInfos.get(chainName);
69
+ }
70
+
71
+ const chainInfo = await E(agoricNames)
72
+ .lookup(CHAIN_KEY, chainName)
73
+ .catch(_cause => {
74
+ throw assert.error(`chain not found:${chainName}`);
75
+ });
76
+ chainInfos.init(chainName, chainInfo);
77
+ return chainInfo;
78
+ },
79
+ /**
80
+ * @param {string} srcChainId
81
+ * @param {string} destChainId
82
+ * @param {IBCConnectionInfo} connectionInfo
83
+ */
84
+ registerConnection(srcChainId, destChainId, connectionInfo) {
85
+ const key = connectionKey(srcChainId, destChainId);
86
+ connectionInfos.init(key, connectionInfo);
87
+ },
88
+
89
+ /**
90
+ * @param {string} srcChainId
91
+ * @param {string} destChainId
92
+ * @returns {Promise<IBCConnectionInfo>}
93
+ */
94
+ async getConnectionInfo(srcChainId, destChainId) {
95
+ const key = connectionKey(srcChainId, destChainId);
96
+ if (connectionInfos.has(key)) {
97
+ return connectionInfos.get(key);
98
+ }
99
+
100
+ const connectionInfo = await E(agoricNames)
101
+ .lookup(CONNECTIONS_KEY, key)
102
+ .catch(_cause => {
103
+ throw assert.error(
104
+ `connection not found: ${srcChainId}<->${destChainId}`,
105
+ );
106
+ });
107
+ connectionInfos.init(key, connectionInfo);
108
+ return connectionInfo;
109
+ },
110
+ });
111
+
112
+ return chainHub;
113
+ };
114
+ /** @typedef {ReturnType<typeof makeChainHub>} ChainHub */
115
+
116
+ /**
117
+ * @param {ERef<import('@agoric/vats').NameHubKit['nameAdmin']>} agoricNamesAdmin
118
+ * @param {string} name
119
+ * @param {CosmosChainInfo} chainInfo
120
+ */
121
+ export const registerChain = async (agoricNamesAdmin, name, chainInfo) => {
122
+ const { nameAdmin } = await E(agoricNamesAdmin).provideChild('chain');
123
+ const { nameAdmin: connAdmin } =
124
+ await E(agoricNamesAdmin).provideChild('chainConnection');
125
+
126
+ mustMatch(chainInfo, CosmosChainInfoShape);
127
+ // XXX chainInfo.connections is redundant here.
128
+ await E(nameAdmin).update(name, chainInfo);
129
+
130
+ for await (const [destChainId, connInfo] of Object.entries(
131
+ chainInfo.connections,
132
+ )) {
133
+ const key = connectionKey(chainInfo.chainId, destChainId);
134
+ await E(connAdmin).update(key, connInfo);
135
+ }
136
+ };
@@ -1,8 +1,5 @@
1
- /**
2
- * @param {TimerService} timer
3
- * @param {TimerBrand} timerBrand
4
- */
5
- export function makeTimestampHelper(timer: TimerService, timerBrand: TimerBrand): {
1
+ /** @param {Remote<TimerService>} timer */
2
+ export function makeTimestampHelper(timer: Remote<TimerService>): {
6
3
  /**
7
4
  * Takes the current time from ChainTimerService and adds a relative time to
8
5
  * determine a timeout timestamp in nanoseconds. Useful for
@@ -16,13 +13,13 @@ export function makeTimestampHelper(timer: TimerService, timerBrand: TimerBrand)
16
13
  };
17
14
  /**
18
15
  * @import {RelativeTimeRecord, TimerBrand, TimerService} from '@agoric/time';
19
- * @import {MsgTransfer} from '@agoric/cosmic-proto/ibc/applications/transfer/v1/tx.js';
16
+ * @import {Remote} from '@agoric/internal';
20
17
  */
21
18
  export const SECONDS_PER_MINUTE: 60n;
22
19
  export const NANOSECONDS_PER_SECOND: 1000000000n;
23
20
  export function dateInSeconds(date: Date): bigint;
24
21
  export type TimestampHelper = Awaited<ReturnType<typeof makeTimestampHelper>>;
25
22
  import type { TimerService } from '@agoric/time';
26
- import type { TimerBrand } from '@agoric/time';
23
+ import type { Remote } from '@agoric/internal';
27
24
  import type { RelativeTimeRecord } from '@agoric/time';
28
25
  //# sourceMappingURL=time.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"time.d.ts","sourceRoot":"","sources":["time.js"],"names":[],"mappings":"AAWA;;;GAGG;AACH;IAEI;;;;;;;;OAQG;0EAFU,OAAO,CAAC,MAAM,CAAC;EAc/B;AAlCD;;;GAGG;AAEH,qCAAsC;AACtC,iDAAqD;AAuC9C,oCAHI,IAAI,GACF,MAAM,CAE2D;8BAThE,OAAO,CAAC,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;kCAnCE,cAAc;gCAAd,cAAc;wCAAd,cAAc"}
1
+ {"version":3,"file":"time.d.ts","sourceRoot":"","sources":["time.js"],"names":[],"mappings":"AAWA,0CAA0C;AAC1C;IAUI;;;;;;;;OAQG;0EAFU,OAAO,CAAC,MAAM,CAAC;EAiB/B;AA1CD;;;GAGG;AAEH,qCAAsC;AACtC,iDAAqD;AA+C9C,oCAHI,IAAI,GACF,MAAM,CAE2D;8BAThE,OAAO,CAAC,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;kCA3CE,cAAc;4BACpD,kBAAkB;wCADoB,cAAc"}
package/src/utils/time.js CHANGED
@@ -3,17 +3,22 @@ import { TimeMath } from '@agoric/time';
3
3
 
4
4
  /**
5
5
  * @import {RelativeTimeRecord, TimerBrand, TimerService} from '@agoric/time';
6
- * @import {MsgTransfer} from '@agoric/cosmic-proto/ibc/applications/transfer/v1/tx.js';
6
+ * @import {Remote} from '@agoric/internal';
7
7
  */
8
8
 
9
9
  export const SECONDS_PER_MINUTE = 60n;
10
10
  export const NANOSECONDS_PER_SECOND = 1_000_000_000n;
11
11
 
12
- /**
13
- * @param {TimerService} timer
14
- * @param {TimerBrand} timerBrand
15
- */
16
- export function makeTimestampHelper(timer, timerBrand) {
12
+ /** @param {Remote<TimerService>} timer */
13
+ export function makeTimestampHelper(timer) {
14
+ /** @type {TimerBrand | undefined} */
15
+ let brandCache;
16
+ const getBrand = async () => {
17
+ if (brandCache) return brandCache;
18
+ brandCache = await E(timer).getTimerBrand();
19
+ return brandCache;
20
+ };
21
+
17
22
  return harden({
18
23
  /**
19
24
  * Takes the current time from ChainTimerService and adds a relative time to
@@ -28,7 +33,10 @@ export function makeTimestampHelper(timer, timerBrand) {
28
33
  const currentTime = await E(timer).getCurrentTimestamp();
29
34
  const timeout =
30
35
  relativeTime ||
31
- TimeMath.coerceRelativeTimeRecord(SECONDS_PER_MINUTE * 5n, timerBrand);
36
+ TimeMath.coerceRelativeTimeRecord(
37
+ SECONDS_PER_MINUTE * 5n,
38
+ await getBrand(),
39
+ );
32
40
  return (
33
41
  TimeMath.addAbsRel(currentTime, timeout).absValue *
34
42
  NANOSECONDS_PER_SECOND