From 8ec70a0ede9d8480f126e0ef3aad6b71e04a4df2 Mon Sep 17 00:00:00 2001 From: 0xPatrick Date: Fri, 29 Nov 2024 16:38:20 -0500 Subject: [PATCH] feat: assetInfo as array of entries - to facililate registering the same denom across multiple chains in `ChainHub` - denoms are unique to a chain, but not all chains --- .../scripts/fast-usdc/init-fast-usdc.js | 28 ++++++++++------- packages/fast-usdc/src/fast-usdc.contract.js | 5 ++-- packages/fast-usdc/src/fast-usdc.start.js | 10 +++++-- packages/fast-usdc/test/supports.ts | 12 ++++---- .../src/examples/send-anywhere.contract.js | 2 +- .../src/proposals/start-send-anywhere.js | 2 +- .../src/utils/chain-hub-helper.js | 9 ++++-- .../orchestration/test/exos/chain-hub.test.ts | 30 +++++++++++-------- 8 files changed, 58 insertions(+), 40 deletions(-) diff --git a/packages/builders/scripts/fast-usdc/init-fast-usdc.js b/packages/builders/scripts/fast-usdc/init-fast-usdc.js index 783ce078f43..f5d38ebee82 100644 --- a/packages/builders/scripts/fast-usdc/init-fast-usdc.js +++ b/packages/builders/scripts/fast-usdc/init-fast-usdc.js @@ -20,31 +20,39 @@ import { parseArgs } from 'node:util'; * @import {ParseArgsConfig} from 'node:util' * @import {FastUSDCConfig} from '@agoric/fast-usdc/src/fast-usdc.start.js' * @import {Passable} from '@endo/marshal'; - * @import {CosmosChainInfo} from '@agoric/orchestration'; + * @import {CosmosChainInfo, Denom, DenomDetail} from '@agoric/orchestration'; */ const { keys } = Object; -const defaultAssetInfo = { - uusdc: { - baseName: 'noble', - chainName: 'noble', - baseDenom: 'uusdc', - }, - [`ibc/${denomHash({ denom: 'uusdc', channelId: fetchedChainInfo.agoric.connections['noble-1'].transferChannel.channelId })}`]: +/** @type {[Denom, DenomDetail & { brandKey?: string}][]} */ +const defaultAssetInfo = [ + [ + 'uusdc', + { + baseName: 'noble', + chainName: 'noble', + baseDenom: 'uusdc', + }, + ], + [ + `ibc/${denomHash({ denom: 'uusdc', channelId: fetchedChainInfo.agoric.connections['noble-1'].transferChannel.channelId })}`, { baseName: 'noble', chainName: 'agoric', baseDenom: 'uusdc', brandKey: 'USDC', }, - [`ibc/${denomHash({ denom: 'uusdc', channelId: fetchedChainInfo.osmosis.connections['noble-1'].transferChannel.channelId })}`]: + ], + [ + `ibc/${denomHash({ denom: 'uusdc', channelId: fetchedChainInfo.osmosis.connections['noble-1'].transferChannel.channelId })}`, { baseName: 'noble', chainName: 'osmosis', baseDenom: 'uusdc', }, -}; + ], +]; /** * @type {Record>} diff --git a/packages/fast-usdc/src/fast-usdc.contract.js b/packages/fast-usdc/src/fast-usdc.contract.js index 91bccb8ddf1..9bf51eacada 100644 --- a/packages/fast-usdc/src/fast-usdc.contract.js +++ b/packages/fast-usdc/src/fast-usdc.contract.js @@ -8,6 +8,7 @@ import { observeIteration, subscribeEach } from '@agoric/notifier'; import { CosmosChainInfoShape, DenomDetailShape, + DenomShape, OrchestrationPowersShape, registerChainsAndAssets, withOrchestration, @@ -60,7 +61,7 @@ export const meta = { feeConfig: FeeConfigShape, marshaller: M.remotable(), chainInfo: M.recordOf(M.string(), CosmosChainInfoShape), - assetInfo: M.recordOf(M.string(), DenomDetailShape), + assetInfo: M.arrayOf([DenomShape, DenomDetailShape]), }, }; harden(meta); @@ -82,7 +83,7 @@ const publishFeeConfig = async (node, marshaller, feeConfig) => { * marshaller: Marshaller; * feeConfig: FeeConfig; * chainInfo: Record; - * assetInfo: Record; + * assetInfo: [Denom, DenomDetail & { brandKey?: string}][]; * }} privateArgs * @param {Zone} zone * @param {OrchestrationTools} tools diff --git a/packages/fast-usdc/src/fast-usdc.start.js b/packages/fast-usdc/src/fast-usdc.start.js index 0dce7f375e2..237af828f30 100644 --- a/packages/fast-usdc/src/fast-usdc.start.js +++ b/packages/fast-usdc/src/fast-usdc.start.js @@ -1,5 +1,9 @@ import { deeplyFulfilledObject, makeTracer, objectMap } from '@agoric/internal'; -import { CosmosChainInfoShape, DenomDetailShape } from '@agoric/orchestration'; +import { + CosmosChainInfoShape, + DenomDetailShape, + DenomShape, +} from '@agoric/orchestration'; import { Fail } from '@endo/errors'; import { E } from '@endo/far'; import { makeMarshal } from '@endo/marshal'; @@ -36,7 +40,7 @@ const contractName = 'fastUsdc'; * feeConfig: FeeConfig; * feedPolicy: FeedPolicy & Passable; * chainInfo: Record; - * assetInfo: Record; + * assetInfo: [Denom, DenomDetail & {brandKey?: string}][]; * }} FastUSDCConfig */ /** @type {TypedPattern} */ @@ -46,7 +50,7 @@ export const FastUSDCConfigShape = M.splitRecord({ feeConfig: FeeConfigShape, feedPolicy: FeedPolicyShape, chainInfo: M.recordOf(M.string(), CosmosChainInfoShape), - assetInfo: M.recordOf(M.string(), DenomDetailShape), + assetInfo: M.arrayOf([DenomShape, DenomDetailShape]), }); /** diff --git a/packages/fast-usdc/test/supports.ts b/packages/fast-usdc/test/supports.ts index 174a28ceed9..2c9154ab227 100644 --- a/packages/fast-usdc/test/supports.ts +++ b/packages/fast-usdc/test/supports.ts @@ -200,13 +200,11 @@ export const commonSetup = async (t: ExecutionContext) => { return { agoric, osmosis, noble }; })(); - const assetInfo = harden( - Object.fromEntries([ - assetOn('uusdc', 'noble'), - [uusdcOnAgoric, agUSDCDetail], - assetOn('uusdc', 'noble', 'osmosis', fetchedChainInfo), - ]), - ); + const assetInfo: [Denom, DenomDetail & { brandKey?: string }][] = harden([ + assetOn('uusdc', 'noble'), + [uusdcOnAgoric, agUSDCDetail], + assetOn('uusdc', 'noble', 'osmosis', fetchedChainInfo), + ]); return { bootstrap: { diff --git a/packages/orchestration/src/examples/send-anywhere.contract.js b/packages/orchestration/src/examples/send-anywhere.contract.js index 3d2065de836..b277d5733ad 100644 --- a/packages/orchestration/src/examples/send-anywhere.contract.js +++ b/packages/orchestration/src/examples/send-anywhere.contract.js @@ -30,7 +30,7 @@ harden(SingleNatAmountRecord); * @param {OrchestrationPowers & { * marshaller: Marshaller; * chainInfo?: Record; - * assetInfo?: Record; + * assetInfo?: [Denom, DenomDetail & { brandKey?: string }][]; * }} privateArgs * @param {Zone} zone * @param {OrchestrationTools} tools diff --git a/packages/orchestration/src/proposals/start-send-anywhere.js b/packages/orchestration/src/proposals/start-send-anywhere.js index a50d87f3f7f..6d1c6932bc1 100644 --- a/packages/orchestration/src/proposals/start-send-anywhere.js +++ b/packages/orchestration/src/proposals/start-send-anywhere.js @@ -28,7 +28,7 @@ const trace = makeTracer('StartSA', true); * @param {{ * options: { * chainInfo: Record; - * assetInfo: Record; + * assetInfo: [Denom, DenomDetail & { brandKey?: string }][]; * }; * }} config */ diff --git a/packages/orchestration/src/utils/chain-hub-helper.js b/packages/orchestration/src/utils/chain-hub-helper.js index 306a5ecef56..829d0b58a7e 100644 --- a/packages/orchestration/src/utils/chain-hub-helper.js +++ b/packages/orchestration/src/utils/chain-hub-helper.js @@ -12,7 +12,7 @@ * @param {ChainHub} chainHub * @param {Record>} brands * @param {Record | undefined} chainInfo - * @param {Record | undefined} assetInfo + * @param {[Denom, DenomDetail & { brandKey?: string }][] | undefined} assetInfo */ export const registerChainsAndAssets = ( chainHub, @@ -43,11 +43,14 @@ export const registerChainsAndAssets = ( } console.log('chainHub: registered connections', [...registeredPairs].sort()); - console.log('chainHub: registering assets', Object.keys(assetInfo || {})); + console.log( + 'chainHub: registering assets', + assetInfo?.map(([denom, { chainName }]) => `${chainName}: ${denom}`), + ); if (!assetInfo) { return; } - for (const [denom, info] of Object.entries(assetInfo)) { + for (const [denom, info] of assetInfo) { const { brandKey, ...rest } = info; const infoWithBrand = brandKey ? { ...rest, brand: brands[brandKey] } diff --git a/packages/orchestration/test/exos/chain-hub.test.ts b/packages/orchestration/test/exos/chain-hub.test.ts index b93e4e34464..53a12302491 100644 --- a/packages/orchestration/test/exos/chain-hub.test.ts +++ b/packages/orchestration/test/exos/chain-hub.test.ts @@ -216,7 +216,10 @@ test('makeTransferRoute - to issuing chain', async t => { chainHub, {}, withChainCapabilities(knownChains), // adds pfmEnabled - harden({ [uusdcOnAgoric]: agDetail, [uusdcOnOsmosis]: osDetail }), + harden([ + [uusdcOnAgoric, agDetail], + [uusdcOnOsmosis, osDetail], + ]), ); const dest: ChainAddress = chainHub.makeChainAddress('noble1234'); @@ -257,12 +260,7 @@ test('makeTransferRoute - from issuing chain', async t => { chainHub, {}, withChainCapabilities(knownChains), // adds pfmEnabled - harden( - Object.fromEntries([ - assetOn('uist', 'agoric'), - assetOn('uosmo', 'osmosis'), - ]), - ), + harden([assetOn('uist', 'agoric'), assetOn('uosmo', 'osmosis')]), ); const dest: ChainAddress = chainHub.makeChainAddress('noble1234'); @@ -301,7 +299,7 @@ test('makeTransferRoute - through issuing chain', async t => { chainHub, {}, withChainCapabilities(knownChains), // adds pfmEnabled - harden({ [uusdcOnAgoric]: agDetail }), + harden([[uusdcOnAgoric, agDetail]]), ); const dest: ChainAddress = chainHub.makeChainAddress('osmo1234'); @@ -359,7 +357,7 @@ test('makeTransferRoute - takes forwardOpts', t => { chainHub, {}, withChainCapabilities(knownChains), // adds pfmEnabled - harden({ [uusdcOnOsmosis]: osDetail }), + harden([[uusdcOnOsmosis, osDetail]]), ); const dest: ChainAddress = chainHub.makeChainAddress('agoric1234'); @@ -464,7 +462,10 @@ test('makeTransferRoute - no connection info single hop', t => { chainHub, {}, knownChainsSansConns, // omit connections - harden({ [uusdcOnAgoric]: agDetail }), + harden([ + [uusdcOnAgoric, agDetail], + [uusdcOnOsmosis, osDetail], + ]), ); t.throws( @@ -487,7 +488,10 @@ test('makeTransferRoute - no connection info multi hop', t => { chainHub, {}, harden(chainInfo), - harden({ [uusdcOnAgoric]: agDetail, [uusdcOnOsmosis]: osDetail }), + harden([ + [uusdcOnAgoric, agDetail], + [uusdcOnOsmosis, osDetail], + ]), ); const osmoDest = chainHub.makeChainAddress('osmo1234'); @@ -522,7 +526,7 @@ test('makeTransferRoute - asset not on holding chain', t => { chainHub, {}, withChainCapabilities(knownChains), - harden({ [uusdcOnAgoric]: agDetail }), + harden([[uusdcOnAgoric, agDetail]]), ); // transfer USDC on agoric from osmosis to noble (impossible) @@ -547,7 +551,7 @@ test('makeTransferRoute - no PFM path', t => { chainHub, {}, knownChains, // intentionally omit pfmEnabled - harden({ [uusdcOnAgoric]: agDetail }), + harden([[uusdcOnAgoric, agDetail]]), ); // transfer USDC on agoric to osmosis