-
Notifications
You must be signed in to change notification settings - Fork 212
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: multichain-testing
makeAssetInfo
helper
- Loading branch information
1 parent
fec9ebc
commit c3403e5
Showing
4 changed files
with
254 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
import test from '@endo/ses-ava/prepare-endo.js'; | ||
import type { Denom, DenomDetail } from '@agoric/orchestration'; | ||
import { makeAssetInfo } from '../../tools/asset-info.js'; | ||
|
||
const minChainInfo = { | ||
agoric: { | ||
chainId: 'agoriclocal', | ||
connections: { | ||
gaialocal: { | ||
transferChannel: { | ||
channelId: 'channel-1', | ||
}, | ||
}, | ||
osmosislocal: { | ||
transferChannel: { | ||
channelId: 'channel-0', | ||
}, | ||
}, | ||
}, | ||
}, | ||
cosmoshub: { | ||
chainId: 'gaialocal', | ||
connections: { | ||
agoriclocal: { | ||
transferChannel: { | ||
channelId: 'channel-1', | ||
}, | ||
}, | ||
osmosislocal: { | ||
transferChannel: { | ||
channelId: 'channel-0', | ||
}, | ||
}, | ||
}, | ||
}, | ||
osmosis: { | ||
chainId: 'osmosislocal', | ||
connections: { | ||
agoriclocal: { | ||
transferChannel: { | ||
channelId: 'channel-1', | ||
}, | ||
}, | ||
gaialocal: { | ||
transferChannel: { | ||
channelId: 'channel-0', | ||
}, | ||
}, | ||
}, | ||
}, | ||
}; | ||
|
||
const minTokenMap = { | ||
agoric: ['ubld', 'uist'], | ||
cosmoshub: ['uatom'], | ||
osmosis: ['uosmo'], | ||
}; | ||
|
||
test('makeAssetInfo', async t => { | ||
const byDenom = (assetInfo: [Denom, DenomDetail][]) => | ||
assetInfo.sort(([a], [b]) => a.localeCompare(b) * -1); | ||
|
||
const assetInfo = makeAssetInfo( | ||
/** @ts-expect-error minified mock */ | ||
minChainInfo, | ||
minTokenMap, | ||
); | ||
|
||
t.deepEqual(byDenom([...assetInfo]), [ | ||
[ | ||
'uosmo', | ||
{ | ||
baseDenom: 'uosmo', | ||
baseName: 'osmosis', | ||
chainName: 'osmosis', | ||
}, | ||
], | ||
[ | ||
'uist', | ||
{ | ||
baseDenom: 'uist', | ||
baseName: 'agoric', | ||
chainName: 'agoric', | ||
}, | ||
], | ||
[ | ||
'ubld', | ||
{ | ||
baseDenom: 'ubld', | ||
baseName: 'agoric', | ||
chainName: 'agoric', | ||
}, | ||
], | ||
[ | ||
'uatom', | ||
{ | ||
baseDenom: 'uatom', | ||
baseName: 'cosmoshub', | ||
chainName: 'cosmoshub', | ||
}, | ||
], | ||
[ | ||
'ibc/ED07A3391A112B175915CD8FAF43A2DA8E4790EDE12566649D0C2F97716B8518', | ||
{ | ||
baseDenom: 'uosmo', | ||
baseName: 'osmosis', | ||
chainName: 'agoric', | ||
}, | ||
], | ||
[ | ||
'ibc/ED07A3391A112B175915CD8FAF43A2DA8E4790EDE12566649D0C2F97716B8518', | ||
{ | ||
baseDenom: 'uosmo', | ||
baseName: 'osmosis', | ||
chainName: 'cosmoshub', | ||
}, | ||
], | ||
[ | ||
'ibc/E7827844CB818EE9C4DB2C159F1543FF62B26213B44CE8029D5CEFE52F0EE596', | ||
{ | ||
baseDenom: 'ubld', | ||
baseName: 'agoric', | ||
chainName: 'cosmoshub', | ||
}, | ||
], | ||
[ | ||
'ibc/E7827844CB818EE9C4DB2C159F1543FF62B26213B44CE8029D5CEFE52F0EE596', | ||
{ | ||
baseDenom: 'ubld', | ||
baseName: 'agoric', | ||
chainName: 'osmosis', | ||
}, | ||
], | ||
[ | ||
'ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9', | ||
{ | ||
baseDenom: 'uatom', | ||
baseName: 'cosmoshub', | ||
chainName: 'agoric', | ||
}, | ||
], | ||
[ | ||
'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2', | ||
{ | ||
baseDenom: 'uatom', | ||
baseName: 'cosmoshub', | ||
chainName: 'osmosis', | ||
}, | ||
], | ||
[ | ||
'ibc/16CD81E12F05F5397CA2D580B4BA786A12A8F48B6FB3823D82EBE95D80B5287B', | ||
{ | ||
baseDenom: 'uist', | ||
baseName: 'agoric', | ||
chainName: 'cosmoshub', | ||
}, | ||
], | ||
[ | ||
'ibc/16CD81E12F05F5397CA2D580B4BA786A12A8F48B6FB3823D82EBE95D80B5287B', | ||
{ | ||
baseDenom: 'uist', | ||
baseName: 'agoric', | ||
chainName: 'osmosis', | ||
}, | ||
], | ||
]); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import { | ||
denomHash, | ||
type CosmosChainInfo, | ||
type Denom, | ||
type DenomDetail, | ||
} from '@agoric/orchestration'; | ||
import type { IBCChannelID } from '@agoric/vats'; | ||
|
||
/** make asset info for current env */ | ||
export const makeAssetInfo = ( | ||
chainInfo: Record<string, CosmosChainInfo>, | ||
tokenMap: Record<string, Denom[]> = { | ||
agoric: ['ubld', 'uist'], | ||
cosmoshub: ['uatom'], | ||
noble: ['uusdc'], | ||
osmosis: ['uosmo', 'uion'], | ||
}, | ||
): [Denom, DenomDetail][] => { | ||
const getChannelId = ( | ||
issuingChainId: string, | ||
holdingChainName: string, | ||
): IBCChannelID | undefined => { | ||
return chainInfo[holdingChainName]?.connections?.[issuingChainId] | ||
.transferChannel.channelId; | ||
}; | ||
|
||
const toDenomHash = ( | ||
denom: Denom, | ||
issuingChainId: string, | ||
holdingChainName: string, | ||
): Denom => { | ||
const channelId = getChannelId(issuingChainId, holdingChainName); | ||
if (!channelId) { | ||
throw new Error( | ||
`No channel found for ${issuingChainId} -> ${holdingChainName}`, | ||
); | ||
} | ||
return `ibc/${denomHash({ denom, channelId })}`; | ||
}; | ||
|
||
// Filter tokenMap to only include chains present in the current environment | ||
const currentTokenMap = Object.entries(tokenMap).reduce< | ||
Record<string, Denom[]> | ||
>( | ||
(acc, [chainName, denoms]) => | ||
chainName in chainInfo ? { ...acc, [chainName]: denoms } : acc, | ||
{}, | ||
); | ||
|
||
const seen = new Set(); | ||
const assetInfo: [Denom, DenomDetail][] = []; | ||
for (const holdingChain of Object.keys(chainInfo)) { | ||
for (const [issuingChain, denoms] of Object.entries(currentTokenMap)) { | ||
for (const denom of denoms) { | ||
const denomOrHash = | ||
holdingChain === issuingChain | ||
? denom | ||
: toDenomHash(denom, chainInfo[issuingChain].chainId, holdingChain); | ||
|
||
const seenKey = `${denomOrHash}-${holdingChain}`; | ||
if (seen.has(seenKey)) continue; | ||
seen.add(seenKey); | ||
assetInfo.push([ | ||
denomOrHash, | ||
{ | ||
baseName: issuingChain, | ||
chainName: holdingChain, | ||
baseDenom: denom, | ||
}, | ||
]); | ||
} | ||
} | ||
} | ||
|
||
return harden(assetInfo); | ||
}; |