From 183c0727da0414d81df8027ce658cd70f4936d2a Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Tue, 4 Jun 2024 13:52:53 -0700 Subject: [PATCH 1/8] feat(typeGuards): CosmosChainInfoShape Co-Authored-By: Dan Connolly --- packages/orchestration/src/typeGuards.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/orchestration/src/typeGuards.js b/packages/orchestration/src/typeGuards.js index 79d48ad3f1c..5c556ca228e 100644 --- a/packages/orchestration/src/typeGuards.js +++ b/packages/orchestration/src/typeGuards.js @@ -37,3 +37,19 @@ export const IBCTransferOptionsShape = M.splitRecord( memo: M.string(), }, ); + +export const CosmosChainInfoShape = M.splitRecord( + { + chainId: M.string(), + connections: M.record(), + stakingTokens: M.arrayOf({ denom: M.string() }), + }, + { + icaEnabled: M.boolean(), + icqEnabled: M.boolean(), + pfmEnabled: M.boolean(), + ibcHooksEnabled: M.boolean(), + allowedMessages: M.arrayOf(M.string()), + allowedQueries: M.arrayOf(M.string()), + }, +); From f7ed627e369f7b0430a891491543029b34a7e2d7 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Tue, 4 Jun 2024 13:53:01 -0700 Subject: [PATCH 2/8] feat(typeGuards): DelegationShape Co-Authored-By: Dan Connolly --- packages/orchestration/src/typeGuards.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/orchestration/src/typeGuards.js b/packages/orchestration/src/typeGuards.js index 5c556ca228e..9ba142f57ec 100644 --- a/packages/orchestration/src/typeGuards.js +++ b/packages/orchestration/src/typeGuards.js @@ -24,7 +24,11 @@ export const ChainAmountShape = harden({ denom: M.string(), value: M.nat() }); export const AmountArgShape = M.or(AmountShape, ChainAmountShape); -export const DelegationShape = M.record(); // TODO: DelegationShape fields +export const DelegationShape = harden({ + delegatorAddress: M.string(), + validatorAddress: M.string(), + shares: M.string(), // TODO: bigint? +}); export const IBCTransferOptionsShape = M.splitRecord( {}, From 303318dacd06e758bdfa693a316fa2db7584235c Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Tue, 4 Jun 2024 15:13:15 -0700 Subject: [PATCH 3/8] test: clarify intentional type errors --- packages/orchestration/test/utils/address.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/orchestration/test/utils/address.test.ts b/packages/orchestration/test/utils/address.test.ts index b637687d5b9..5e624feb000 100644 --- a/packages/orchestration/test/utils/address.test.ts +++ b/packages/orchestration/test/utils/address.test.ts @@ -7,11 +7,11 @@ import { } from '../../src/utils/address.js'; test('makeICAChannelAddress', t => { - // @ts-expect-error expected two arguments + // @ts-expect-error intentional t.throws(() => makeICAChannelAddress(), { message: 'hostConnectionId is required', }); - // @ts-expect-error expected two arguments + // @ts-expect-error intentional t.throws(() => makeICAChannelAddress('connection-0'), { message: 'controllerConnectionId is required', }); @@ -74,7 +74,7 @@ test('findAddressField', t => { }); test('makeICQChannelAddress', t => { - // @ts-expect-error expected 1 argument + // @ts-expect-error intentional t.throws(() => makeICQChannelAddress(), { message: 'controllerConnectionId is required', }); From 8c6c757f744be6d284ca809d009c8b1869f05c03 Mon Sep 17 00:00:00 2001 From: Dan Connolly Date: Tue, 21 May 2024 15:39:43 -0500 Subject: [PATCH 4/8] chore: include stakingTokens denom in CosmosChainInfo --- packages/orchestration/src/cosmos-api.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/orchestration/src/cosmos-api.ts b/packages/orchestration/src/cosmos-api.ts index 134628e4462..702a2d30e46 100644 --- a/packages/orchestration/src/cosmos-api.ts +++ b/packages/orchestration/src/cosmos-api.ts @@ -77,6 +77,11 @@ export type CosmosChainInfo = { */ allowedMessages: TypeUrl[]; allowedQueries: TypeUrl[]; + + /** + * cf https://github.com/cosmos/chain-registry/blob/master/chain.schema.json#L117 + */ + stakingTokens?: Array<{ denom: string }>; }; export interface StakingAccountQueries { From 9d38e2eb19496b85e6abdf7fcd7cf16c4581b3ce Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Tue, 4 Jun 2024 14:18:07 -0700 Subject: [PATCH 5/8] feat: registerChain --- packages/orchestration/src/facade.js | 59 ++++++++++----- packages/orchestration/test/facade.test.ts | 86 ++++++++++++++++++++++ 2 files changed, 126 insertions(+), 19 deletions(-) create mode 100644 packages/orchestration/test/facade.test.ts diff --git a/packages/orchestration/src/facade.js b/packages/orchestration/src/facade.js index 33fb0107e33..6ee549fd326 100644 --- a/packages/orchestration/src/facade.js +++ b/packages/orchestration/src/facade.js @@ -1,7 +1,11 @@ /** @file Orchestration service */ +import { makeScalarBigMapStore } from '@agoric/vat-data'; import { E } from '@endo/far'; +import { M } from '@endo/patterns'; +import { wellKnownChainInfo } from './chain-info.js'; import { prepareCosmosOrchestrationAccount } from './exos/cosmosOrchestrationAccount.js'; +import { CosmosChainInfoShape } from './typeGuards.js'; /** * @import {Zone} from '@agoric/zone'; @@ -82,27 +86,21 @@ const makeLocalChainFacade = localchain => { }; /** - * @template {string} C - * @param {C} name + * @template {CosmosChainInfo} CCI + * @param {CCI} chainInfo * @param {object} io * @param {Remote} io.orchestration * @param {Remote} io.timer * @param {ZCF} io.zcf * @param {Zone} io.zone - * @returns {Chain} + * @returns {Chain} */ -const makeRemoteChainFacade = (name, { orchestration, timer, zcf, zone }) => { - const chainInfo = /** @type {CosmosChainInfo} */ ({ - allegedName: name, - chainId: 'fixme', - connections: {}, - icaEnabled: true, - icqEnabled: true, - pfmEnabled: true, - ibcHooksEnabled: true, - allowedMessages: [], - allowedQueries: [], - }); +const makeRemoteChainFacade = ( + chainInfo, + { orchestration, timer, zcf, zone }, +) => { + const name = chainInfo.chainId; + const makeRecorderKit = () => anyVal; const makeCosmosOrchestrationAccount = prepareCosmosOrchestrationAccount( zone.subZone(name), @@ -112,7 +110,7 @@ const makeRemoteChainFacade = (name, { orchestration, timer, zcf, zone }) => { return { getChainInfo: async () => chainInfo, - /** @returns {Promise>} */ + /** @returns {Promise>} */ makeAccount: async () => { console.log('makeAccount for', name); @@ -165,12 +163,33 @@ export const makeOrchestrationFacade = ({ orchestrationService, }); + const chainInfos = makeScalarBigMapStore('chainInfos', { + keyShape: M.string(), + valueShape: CosmosChainInfoShape, + }); + return { + /** + * Register a new chain in a heap store. The name will override a name in + * well known chain names. + * + * This registration will not surve a reincarnation of the vat so if the + * chain is not yet in the well known names at that point, it will have to + * be registered again. In an unchanged contract `start` the call will + * happen again naturally. + * + * @param {string} name + * @param {ChainInfo} chainInfo + */ + registerChain(name, chainInfo) { + chainInfos.init(name, chainInfo); + }, /** * @template Context * @template {any[]} Args - * @param {string} durableName - * @param {Context} ctx + * @param {string} durableName - the orchestration flow identity in the zone + * (to resume across upgrades) + * @param {Context} ctx - values to pass through the async flow membrane * @param {(orc: Orchestrator, ctx2: Context, ...args: Args) => object} fn * @returns {(...args: Args) => Promise} */ @@ -182,7 +201,9 @@ export const makeOrchestrationFacade = ({ return makeLocalChainFacade(localchain); } - return makeRemoteChainFacade(name, { + const chainInfo = chainInfos.get(name); + + return makeRemoteChainFacade(chainInfo, { orchestration: orchestrationService, timer: timerService, zcf, diff --git a/packages/orchestration/test/facade.test.ts b/packages/orchestration/test/facade.test.ts new file mode 100644 index 00000000000..bfe30bf6a9a --- /dev/null +++ b/packages/orchestration/test/facade.test.ts @@ -0,0 +1,86 @@ +import { test as anyTest } from '@agoric/zoe/tools/prepare-test-env-ava.js'; + +import { setupZCFTest } from '@agoric/zoe/test/unitTests/zcf/setupZcfTest.js'; +import type { CosmosChainInfo } from '../src/cosmos-api.js'; +import { makeOrchestrationFacade } from '../src/facade.js'; +import type { Chain } from '../src/orchestration-api.js'; +import { commonSetup } from './supports.js'; + +const test = anyTest; + +export const mockChainInfo: CosmosChainInfo = harden({ + chainId: 'mock-1', + connections: {}, + icaEnabled: false, + icqEnabled: false, + pfmEnabled: false, + ibcHooksEnabled: false, + allowedMessages: [], + allowedQueries: [], + stakingTokens: [{ denom: 'umock' }], +}); + +test('chain info', async t => { + const { bootstrap } = await commonSetup(t); + + const zone = bootstrap.rootZone; + + const { zcf } = await setupZCFTest(); + + const { registerChain, orchestrate } = makeOrchestrationFacade({ + localchain: bootstrap.localchain, + orchestrationService: bootstrap.orchestration, + storageNode: bootstrap.storage.rootNode, + timerService: bootstrap.timer, + zcf, + zone, + }); + + registerChain('mock', mockChainInfo); + + const handle = orchestrate('mock', {}, async orc => { + return orc.getChain('mock'); + }); + + const result = (await handle()) as Chain<'mock'>; + t.deepEqual(await result.getChainInfo(), mockChainInfo); +}); + +test('contract upgrade', async t => { + const { bootstrap } = await commonSetup(t); + + const zone = bootstrap.rootZone; + + const { zcf } = await setupZCFTest(); + + // Register once + { + const { registerChain } = makeOrchestrationFacade({ + localchain: bootstrap.localchain, + orchestrationService: bootstrap.orchestration, + storageNode: bootstrap.storage.rootNode, + timerService: bootstrap.timer, + zcf, + zone, + }); + registerChain('mock', mockChainInfo); + + // cannot register again in this incarnation + t.throws(() => registerChain('mock', mockChainInfo), { + message: 'key "mock" already registered in collection "chainInfos"', + }); + } + + // Simulate running again in a new incarnation with the same zone + { + const { registerChain } = makeOrchestrationFacade({ + localchain: bootstrap.localchain, + orchestrationService: bootstrap.orchestration, + storageNode: bootstrap.storage.rootNode, + timerService: bootstrap.timer, + zcf, + zone, + }); + registerChain('mock', mockChainInfo); + } +}); From bdd68cfaef52d49f90346c483474a2e18a6312b5 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Tue, 4 Jun 2024 14:54:17 -0700 Subject: [PATCH 6/8] chore(types): Chain parameterized by ChainInfo --- packages/orchestration/src/chain-info.js | 60 +++++++++++++++++ packages/orchestration/src/chain-info.ts | 64 ------------------- packages/orchestration/src/cosmos-api.ts | 12 ++++ packages/orchestration/src/facade.js | 14 ++-- .../orchestration/src/orchestration-api.ts | 30 +++++---- packages/orchestration/test/facade.test.ts | 2 +- 6 files changed, 102 insertions(+), 80 deletions(-) create mode 100644 packages/orchestration/src/chain-info.js delete mode 100644 packages/orchestration/src/chain-info.ts diff --git a/packages/orchestration/src/chain-info.js b/packages/orchestration/src/chain-info.js new file mode 100644 index 00000000000..fe7352ca004 --- /dev/null +++ b/packages/orchestration/src/chain-info.js @@ -0,0 +1,60 @@ +// UNTIL https://github.com/Agoric/agoric-sdk/issues/8879 + +/** @file temporary static lookup of chain info */ + +/** @import {CosmosChainInfo, EthChainInfo} from './types.js'; */ + +/** @typedef {CosmosChainInfo | EthChainInfo} ChainInfo */ + +// TODO generate this automatically with a build script drawing on data sources such as https://github.com/cosmos/chain-registry + +export const wellKnownChainInfo = + /** @satisfies {Record} */ ( + harden({ + // https://github.com/cosmos/chain-registry/blob/master/stride/chain.json + stride: { + chainId: 'stride-1', + connections: {}, + icaEnabled: true, + icqEnabled: true, + pfmEnabled: true, + ibcHooksEnabled: true, + allowedMessages: [], + allowedQueries: [], + stakingTokens: [{ denom: 'ustride' }], + }, + cosmos: { + chainId: 'cosmoshub-4', + connections: {}, + icaEnabled: true, + icqEnabled: true, + pfmEnabled: true, + ibcHooksEnabled: true, + allowedMessages: [], + allowedQueries: [], + stakingTokens: [{ denom: 'uatom' }], + }, + celestia: { + chainId: 'celestia', + connections: {}, + icaEnabled: true, + icqEnabled: true, + pfmEnabled: true, + ibcHooksEnabled: true, + allowedMessages: [], + allowedQueries: [], + stakingTokens: [{ denom: 'utia' }], + }, + osmosis: { + chainId: 'osmosis-1', + connections: {}, + icaEnabled: true, + icqEnabled: true, + pfmEnabled: true, + ibcHooksEnabled: true, + allowedMessages: [], + allowedQueries: [], + stakingTokens: [{ denom: 'uosmo' }], + }, + }) + ); diff --git a/packages/orchestration/src/chain-info.ts b/packages/orchestration/src/chain-info.ts deleted file mode 100644 index c916d8f8019..00000000000 --- a/packages/orchestration/src/chain-info.ts +++ /dev/null @@ -1,64 +0,0 @@ -/** - * @file static declaration of known chain types will allow type support for - * additional chain-specific operations like `liquidStake` - */ - -import type { - CosmosChainInfo, - EthChainInfo, - IcaAccount, - ICQConnection, - LiquidStakingMethods, - StakingAccountActions, - StakingAccountQueries, -} from './types.js'; - -export type ChainInfo = CosmosChainInfo | EthChainInfo; - -// TODO generate this automatically with a build script drawing on data sources such as https://github.com/cosmos/chain-registry - -// XXX methods ad-hoc and not fully accurate -export type KnownChains = Record & { - stride: { - info: CosmosChainInfo; - methods: IcaAccount & - ICQConnection & - StakingAccountActions & - StakingAccountQueries & - LiquidStakingMethods; - }; - cosmos: { - info: CosmosChainInfo; - methods: IcaAccount & - ICQConnection & - StakingAccountActions & - StakingAccountQueries; - }; - agoric: { - info: CosmosChainInfo; - methods: { - // TODO reference type from #8624 `packages/vats/src/localchain.js` - /** - * Register a hook to intercept an incoming IBC Transfer and handle it. - * Calling without arguments will unregister the hook. - */ - interceptTransfer: (tap?: { - upcall: (args: any) => Promise; - }) => Promise; - }; - }; - celestia: { - info: CosmosChainInfo; - methods: IcaAccount & - ICQConnection & - StakingAccountActions & - StakingAccountQueries; - }; - osmosis: { - info: CosmosChainInfo; - methods: IcaAccount & - ICQConnection & - StakingAccountActions & - StakingAccountQueries; - }; -}; diff --git a/packages/orchestration/src/cosmos-api.ts b/packages/orchestration/src/cosmos-api.ts index 702a2d30e46..04cebb79777 100644 --- a/packages/orchestration/src/cosmos-api.ts +++ b/packages/orchestration/src/cosmos-api.ts @@ -224,3 +224,15 @@ export type IBCMsgTransferOptions = { timeoutTimestamp?: MsgTransfer['timeoutTimestamp']; memo?: string; }; + +export type CosmosChainAccountMethods = + (CCI extends { + icaEnabled: true; + } + ? IcaAccount + : {}) & + CCI extends { + stakingTokens: {}; + } + ? StakingAccountActions + : {}; diff --git a/packages/orchestration/src/facade.js b/packages/orchestration/src/facade.js index 6ee549fd326..480a608a4c8 100644 --- a/packages/orchestration/src/facade.js +++ b/packages/orchestration/src/facade.js @@ -13,7 +13,7 @@ import { CosmosChainInfoShape } from './typeGuards.js'; * @import {LocalChain} from '@agoric/vats/src/localchain.js'; * @import {Remote} from '@agoric/internal'; * @import {OrchestrationService} from './service.js'; - * @import {Chain, ChainInfo, CosmosChainInfo, KnownChains, OrchestrationAccount, Orchestrator} from './types.js'; + * @import {Chain, ChainInfo, CosmosChainInfo, OrchestrationAccount, Orchestrator} from './types.js'; */ /** @type {any} */ @@ -93,7 +93,7 @@ const makeLocalChainFacade = localchain => { * @param {Remote} io.timer * @param {ZCF} io.zcf * @param {Zone} io.zone - * @returns {Chain} + * @returns {Chain} */ const makeRemoteChainFacade = ( chainInfo, @@ -110,7 +110,7 @@ const makeRemoteChainFacade = ( return { getChainInfo: async () => chainInfo, - /** @returns {Promise>} */ + /** @returns {Promise>} */ makeAccount: async () => { console.log('makeAccount for', name); @@ -127,6 +127,7 @@ const makeRemoteChainFacade = ( // FIXME look up real values const bondDenom = name; + // @ts-expect-error XXX dynamic method availability return makeCosmosOrchestrationAccount(address, bondDenom, { account: icaAccount, storageNode: anyVal, @@ -201,7 +202,12 @@ export const makeOrchestrationFacade = ({ return makeLocalChainFacade(localchain); } - const chainInfo = chainInfos.get(name); + // TODO look up well known realistically https://github.com/Agoric/agoric-sdk/issues/9063 + const chainInfo = chainInfos.has(name) + ? chainInfos.get(name) + : // @ts-expect-error may be undefined + wellKnownChainInfo[name]; + assert(chainInfo, `unknown chain ${name}`); return makeRemoteChainFacade(chainInfo, { orchestration: orchestrationService, diff --git a/packages/orchestration/src/orchestration-api.ts b/packages/orchestration/src/orchestration-api.ts index 0f022b3c336..9653caae2ae 100644 --- a/packages/orchestration/src/orchestration-api.ts +++ b/packages/orchestration/src/orchestration-api.ts @@ -12,7 +12,15 @@ import type { } from '@agoric/ertp/src/types.js'; import type { LocalChainAccount } from '@agoric/vats/src/localchain.js'; import type { Timestamp } from '@agoric/time'; -import type { IBCMsgTransferOptions, KnownChains } from './types.js'; +import type { + ChainInfo, + CosmosChainAccountMethods, + CosmosChainInfo, + IBCMsgTransferOptions, + wellKnownChainInfo, +} from './types.js'; + +type KnownChains = typeof wellKnownChainInfo; /** * A denom that designates a path to a token type on some blockchain. @@ -57,8 +65,8 @@ export type ChainAddress = { addressEncoding: 'bech32' | 'ethereum'; }; -export type OrchestrationAccount = - OrchestrationAccountI & KnownChains[C]['methods']; +export type OrchestrationAccount = OrchestrationAccountI & + (CI extends CosmosChainInfo ? CosmosChainAccountMethods : never); /** * An object for access the core functions of a remote chain. @@ -66,15 +74,15 @@ export type OrchestrationAccount = * Note that "remote" can mean the local chain; it's just that * accounts are treated as remote/arms length for consistency. */ -export interface Chain { - getChainInfo: () => Promise; +export interface Chain { + getChainInfo: () => Promise; // "makeAccount" suggests an operation within a vat /** * Creates a new account on the remote chain. * @returns an object that controls a new remote account on Chain */ - makeAccount: () => Promise>; + makeAccount: () => Promise>; // FUTURE supply optional port object; also fetch port object // TODO provide a way to get the local denom/brand/whatever for this chain @@ -84,9 +92,9 @@ export interface Chain { * Provided in the callback to `orchestrate()`. */ export interface Orchestrator { - // TODO we need a way to work with a chain its native way vs generic way - // E.g. an Osmosis delegate that looks Cosmos-y or no different from an Ethereum delegate - getChain: (chainName: C) => Promise>; + getChain: ( + chainName: C, + ) => Promise>; makeLocalAccount: () => Promise; /** @@ -104,9 +112,9 @@ export interface Orchestrator { /** The well-known Brand on Agoric for the direct asset */ brand?: Brand; /** The Chain at which the argument `denom` exists (where the asset is currently held) */ - chain: Chain; + chain: Chain; /** The Chain that is the issuer of the underlying asset */ - base: Chain; + base: Chain; /** the Denom for the underlying asset on its issuer chain */ baseDenom: Denom; }; diff --git a/packages/orchestration/test/facade.test.ts b/packages/orchestration/test/facade.test.ts index bfe30bf6a9a..10fdfa1c162 100644 --- a/packages/orchestration/test/facade.test.ts +++ b/packages/orchestration/test/facade.test.ts @@ -42,7 +42,7 @@ test('chain info', async t => { return orc.getChain('mock'); }); - const result = (await handle()) as Chain<'mock'>; + const result = (await handle()) as Chain; t.deepEqual(await result.getChainInfo(), mockChainInfo); }); From 82115f1dfc6e834beecdc8def2b2a684d3952d06 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Tue, 4 Jun 2024 15:35:19 -0700 Subject: [PATCH 7/8] fix: get bondDenom from chainInfo --- packages/orchestration/src/facade.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/orchestration/src/facade.js b/packages/orchestration/src/facade.js index 480a608a4c8..dc4840b9aac 100644 --- a/packages/orchestration/src/facade.js +++ b/packages/orchestration/src/facade.js @@ -112,8 +112,6 @@ const makeRemoteChainFacade = ( getChainInfo: async () => chainInfo, /** @returns {Promise>} */ makeAccount: async () => { - console.log('makeAccount for', name); - // FIXME look up real values const hostConnectionId = 'connection-1'; const controllerConnectionId = 'connection-2'; @@ -125,8 +123,12 @@ const makeRemoteChainFacade = ( const address = await E(icaAccount).getAddress(); - // FIXME look up real values - const bondDenom = name; + const [{ denom: bondDenom }] = chainInfo.stakingTokens || [ + { + denom: null, + }, + ]; + assert(bondDenom, 'missing bondDenom'); // @ts-expect-error XXX dynamic method availability return makeCosmosOrchestrationAccount(address, bondDenom, { account: icaAccount, From 6d597fd83d7f0a003bcc5a5cd1a138b74114d01f Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Tue, 4 Jun 2024 15:11:13 -0700 Subject: [PATCH 8/8] chore: facade reconciliation --- packages/orchestration/src/facade.js | 31 +++++++++++++++++----------- packages/vats/src/localchain.js | 2 +- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/packages/orchestration/src/facade.js b/packages/orchestration/src/facade.js index dc4840b9aac..b9ea70bfeea 100644 --- a/packages/orchestration/src/facade.js +++ b/packages/orchestration/src/facade.js @@ -19,7 +19,8 @@ import { CosmosChainInfoShape } from './typeGuards.js'; /** @type {any} */ const anyVal = null; -// FIXME should be configurable +// FIXME look up real values +// UNTIL https://github.com/Agoric/agoric-sdk/issues/9063 const mockLocalChainInfo = { allegedName: 'agoric', allowedMessages: [], @@ -43,36 +44,41 @@ const makeLocalChainFacade = localchain => { return mockLocalChainInfo; }, - // @ts-expect-error FIXME promise resolution through membrane async makeAccount() { const account = await E(localchain).makeAccount(); return { - deposit(payment) { + async deposit(payment) { console.log('deposit got', payment); - return E(account).deposit(payment); + await E(account).deposit(payment); }, - async getAddress() { - const addressStr = await E(account).getAddress(); + getAddress() { + const addressStr = account.getAddress(); return { address: addressStr, chainId: mockLocalChainInfo.chainId, addressEncoding: 'bech32', }; }, - getBalance(_denom) { - // FIXME map denom to Brand - const brand = /** @type {any} */ (null); - return E(account).getBalance(brand); + async getBalance(denomArg) { + // FIXME look up real values + // UNTIL https://github.com/Agoric/agoric-sdk/issues/9211 + const [brand, denom] = + typeof denomArg === 'string' + ? [/** @type {any} */ (null), denomArg] + : [denomArg, 'FIXME']; + + const natAmount = await account.getBalance(brand); + return harden({ denom, value: natAmount.value }); }, getBalances() { throw new Error('not yet implemented'); }, - send(toAccount, amount) { + async send(toAccount, amount) { // FIXME implement console.log('send got', toAccount, amount); }, - transfer(amount, destination, opts) { + async transfer(amount, destination, opts) { // FIXME implement console.log('transfer got', amount, destination, opts); }, @@ -113,6 +119,7 @@ const makeRemoteChainFacade = ( /** @returns {Promise>} */ makeAccount: async () => { // FIXME look up real values + // UNTIL https://github.com/Agoric/agoric-sdk/issues/9063 const hostConnectionId = 'connection-1'; const controllerConnectionId = 'connection-2'; diff --git a/packages/vats/src/localchain.js b/packages/vats/src/localchain.js index b2fbefc48b9..1ec1441d6f8 100644 --- a/packages/vats/src/localchain.js +++ b/packages/vats/src/localchain.js @@ -45,7 +45,7 @@ const prepareLocalChainAccount = zone => (address, powers) => ({ address, ...powers, reserved: undefined }), { // Information that the account creator needs. - async getAddress() { + getAddress() { return this.state.address; }, /** @param {Brand<'nat'>} brand */