From fec9ebc708a4f0305f3ecd47fc84307368fe3b0d Mon Sep 17 00:00:00 2001 From: 0xPatrick Date: Fri, 29 Nov 2024 14:47:23 -0500 Subject: [PATCH] feat!: `getAsset` and `getDenomInfo` require `holdingChainName` param - since denoms are only unique to a chain and all chains, require `holdingChainName` parameter for asset info lookups --- .../snapshots/fast-usdc.contract.test.ts.md | 14 +++---- .../snapshots/fast-usdc.contract.test.ts.snap | Bin 5637 -> 5637 bytes packages/orchestration/src/exos/chain-hub.js | 37 ++++++++++++++---- .../src/exos/local-orchestration-account.js | 2 +- .../orchestration/src/exos/orchestrator.js | 6 +-- .../orchestration/src/orchestration-api.ts | 1 + .../snapshots/staking-combinations.test.ts.md | 2 +- .../staking-combinations.test.ts.snap | Bin 2743 -> 2749 bytes .../orchestration/test/exos/chain-hub.test.ts | 21 +++++----- .../test/facade-durability.test.ts | 26 +++++++----- packages/orchestration/test/supports.ts | 2 +- packages/orchestration/test/types.test-d.ts | 2 +- 12 files changed, 73 insertions(+), 40 deletions(-) diff --git a/packages/fast-usdc/test/snapshots/fast-usdc.contract.test.ts.md b/packages/fast-usdc/test/snapshots/fast-usdc.contract.test.ts.md index 62804cfa992..ece2a6e83cd 100644 --- a/packages/fast-usdc/test/snapshots/fast-usdc.contract.test.ts.md +++ b/packages/fast-usdc/test/snapshots/fast-usdc.contract.test.ts.md @@ -536,22 +536,22 @@ Generated by [AVA](https://avajs.dev). }, }, denom: { - 'ibc/498A0751C798A0D9A389AA3691123DADA57DAA4FE165D5C75894505B876BA6E4': { - baseDenom: 'uusdc', - baseName: 'noble', - chainName: 'osmosis', - }, - 'ibc/FE98AAD68F02F03565E9FA39A5E627946699B2B07115889ED812D8BA639576A9': { + 'agoric:ibc/FE98AAD68F02F03565E9FA39A5E627946699B2B07115889ED812D8BA639576A9': { baseDenom: 'uusdc', baseName: 'noble', brand: Object @Alleged: USDC brand {}, chainName: 'agoric', }, - uusdc: { + 'noble:uusdc': { baseDenom: 'uusdc', baseName: 'noble', chainName: 'noble', }, + 'osmosis:ibc/498A0751C798A0D9A389AA3691123DADA57DAA4FE165D5C75894505B876BA6E4': { + baseDenom: 'uusdc', + baseName: 'noble', + chainName: 'osmosis', + }, }, lookupChainInfo_kindHandle: 'Alleged: kind', lookupChainsAndConnection_kindHandle: 'Alleged: kind', diff --git a/packages/fast-usdc/test/snapshots/fast-usdc.contract.test.ts.snap b/packages/fast-usdc/test/snapshots/fast-usdc.contract.test.ts.snap index 084687b3bab0cbb2441b180c061d6ebbda934d4e..b4f6db225e5d35f97fc59405cd299d04a75b129f 100644 GIT binary patch literal 5637 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 literal 5637 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 diff --git a/packages/orchestration/src/exos/chain-hub.js b/packages/orchestration/src/exos/chain-hub.js index f74d9eda964..00ce386c572 100644 --- a/packages/orchestration/src/exos/chain-hub.js +++ b/packages/orchestration/src/exos/chain-hub.js @@ -205,7 +205,9 @@ const ChainHubI = M.interface('ChainHub', { getConnectionInfo: M.call(ChainIdArgShape, ChainIdArgShape).returns(VowShape), getChainsAndConnection: M.call(M.string(), M.string()).returns(VowShape), registerAsset: M.call(M.string(), DenomDetailShape).returns(), - getAsset: M.call(M.string()).returns(M.or(DenomDetailShape, M.undefined())), + getAsset: M.call(M.string(), M.string()).returns( + M.or(DenomDetailShape, M.undefined()), + ), getDenom: M.call(BrandShape).returns(M.or(M.string(), M.undefined())), makeChainAddress: M.call(M.string()).returns(ChainAddressShape), makeTransferRoute: M.call(ChainAddressShape, DenomAmountShape, M.string()) @@ -256,6 +258,14 @@ export const makeChainHub = (zone, agoricNames, vowTools) => { valueShape: M.string(), }); + /** + * @param {Denom} denom - on the holding chain, whose name is given in + * `detail.chainName` + * @param {DenomDetail['chainName']} holdingChainName + */ + const makeDenomKey = (denom, holdingChainName) => + `${holdingChainName}:${denom}`; + const lookupChainInfo = vowTools.retryable( zone, 'lookupChainInfo', @@ -440,8 +450,14 @@ export const makeChainHub = (zone, agoricNames, vowTools) => { Fail`must register chain ${q(chainName)} first`; chainInfos.has(baseName) || Fail`must register chain ${q(baseName)} first`; - denomDetails.init(denom, detail); + + const denomKey = makeDenomKey(denom, detail.chainName); + denomDetails.has(denomKey) && + Fail`already registered ${q(denom)} on ${q(chainName)}`; + denomDetails.init(denomKey, detail); if (detail.brand) { + chainName === 'agoric' || + Fail`brands only registerable for agoric-held assets`; brandDenoms.init(detail.brand, denom); } }, @@ -449,11 +465,13 @@ export const makeChainHub = (zone, agoricNames, vowTools) => { * Retrieve holding, issuing chain names etc. for a denom. * * @param {Denom} denom + * @param {string} holdingChainName - the chainName the denom is held on * @returns {DenomDetail | undefined} */ - getAsset(denom) { - if (denomDetails.has(denom)) { - return denomDetails.get(denom); + getAsset(denom, holdingChainName) { + const denomKey = makeDenomKey(denom, holdingChainName); + if (denomDetails.has(denomKey)) { + return denomDetails.get(denomKey); } return undefined; }, @@ -504,11 +522,16 @@ export const makeChainHub = (zone, agoricNames, vowTools) => { chainInfos.has(holdingChainName) || Fail`chain info not found for holding chain: ${q(holdingChainName)}`; - const denomDetail = chainHub.getAsset(denomAmount.denom); + const denomDetail = chainHub.getAsset( + denomAmount.denom, + holdingChainName, + ); denomDetail || - Fail`no denom detail for: ${q(denomAmount.denom)}. ensure it is registered in chainHub.`; + Fail`no denom detail for: ${q(denomAmount.denom)} on ${q(holdingChainName)}. ensure it is registered in chainHub.`; const { baseName, chainName } = /** @type {DenomDetail} */ (denomDetail); + + // currently unreachable since assets are registered with holdingChainName chainName === holdingChainName || Fail`cannot transfer asset ${q(denomAmount.denom)}. held on ${q(chainName)} not ${q(holdingChainName)}.`; diff --git a/packages/orchestration/src/exos/local-orchestration-account.js b/packages/orchestration/src/exos/local-orchestration-account.js index bc5e1f2a48a..7ab823a0719 100644 --- a/packages/orchestration/src/exos/local-orchestration-account.js +++ b/packages/orchestration/src/exos/local-orchestration-account.js @@ -511,7 +511,7 @@ export const prepareLocalOrchestrationAccountKit = ( return asVow(() => { const [brand, denom] = typeof denomArg === 'string' - ? [chainHub.getAsset(denomArg)?.brand, denomArg] + ? [chainHub.getAsset(denomArg, 'agoric')?.brand, denomArg] : [denomArg, chainHub.getDenom(denomArg)]; if (!denom) { diff --git a/packages/orchestration/src/exos/orchestrator.js b/packages/orchestration/src/exos/orchestrator.js index 70e02ee60e7..0d5dae350b8 100644 --- a/packages/orchestration/src/exos/orchestrator.js +++ b/packages/orchestration/src/exos/orchestrator.js @@ -34,7 +34,7 @@ const trace = makeTracer('Orchestrator'); /** @see {Orchestrator} */ export const OrchestratorI = M.interface('Orchestrator', { getChain: M.call(M.string()).returns(Vow$(ChainInfoShape)), - getDenomInfo: M.call(DenomShape).returns(DenomInfoShape), + getDenomInfo: M.call(DenomShape, M.string()).returns(DenomInfoShape), asAmount: M.call(DenomAmountShape).returns(AmountShape), }); @@ -138,8 +138,8 @@ const prepareOrchestratorKit = ( }); }, /** @type {HostOf} */ - getDenomInfo(denom) { - const denomDetail = chainHub.getAsset(denom); + getDenomInfo(denom, holdingChainName) { + const denomDetail = chainHub.getAsset(denom, holdingChainName); if (!denomDetail) throw Fail`No denom detail for ${q(denom)}`; const { chainName, baseName, baseDenom, brand } = denomDetail; chainByName.has(chainName) || diff --git a/packages/orchestration/src/orchestration-api.ts b/packages/orchestration/src/orchestration-api.ts index 50830862c05..112611325ef 100644 --- a/packages/orchestration/src/orchestration-api.ts +++ b/packages/orchestration/src/orchestration-api.ts @@ -146,6 +146,7 @@ export interface Orchestrator { IssuingChain extends keyof KnownChains, >( denom: Denom, + holdingChainName: HoldingChain, ) => DenomInfo; /** diff --git a/packages/orchestration/test/examples/snapshots/staking-combinations.test.ts.md b/packages/orchestration/test/examples/snapshots/staking-combinations.test.ts.md index bbf2ad9192b..378cdaddaf7 100644 --- a/packages/orchestration/test/examples/snapshots/staking-combinations.test.ts.md +++ b/packages/orchestration/test/examples/snapshots/staking-combinations.test.ts.md @@ -98,7 +98,7 @@ Generated by [AVA](https://avajs.dev). }, }, denom: { - ubld: { + 'agoric:ubld': { baseDenom: 'ubld', baseName: 'agoric', brand: Object @Alleged: BLD brand {}, diff --git a/packages/orchestration/test/examples/snapshots/staking-combinations.test.ts.snap b/packages/orchestration/test/examples/snapshots/staking-combinations.test.ts.snap index 01a323d924f17902e88e58d2a0c44d1e0f98fc89..89494e9934d40e5f508d23d3c19b809d99d905d1 100644 GIT binary patch literal 2749 zcmV;u3PSZkRzV zIU=KM;U9|#00000000B+T5W6`M;U(R?DO6E<38*=pFhs_*^c9n*v5A3ghZ`W$B7j~ zT$_9f6$pEK=`XptgS6oF`~(xN~`p{**Y6d|Na&`<%QQvXmY z5v4*^grYV=6$H`U^X=`58zbFRO-r@u_rLFoZ9Tq6$8k|A?RXX8{}m@ECyK0=Nd?KLA{q*A;PAR@W@k4;?1IxGYG@;atkH zyyvp0ilGUjVOd5!MN5OKiOWd*K~6f8-C&ee(nKodVqaZfL;Z> zR0UL31AW!NSE_;UR|CJP2Ci2F0WUMM9{0%lN!@*3VAczK!wdY%3taO8r~wi+z`ZrV z@fzS#4e)jiBjsbI0=+(9&<8C0fS>t*4}HMAAISNEOMc)Fenz65lV}V8Edf9d0Ivps z+W}yIEpVY0c)S*Pp_Y*tVI_QT)B=D02p+EkGIhX@>VWHYKzBVuo#LXbo{5mw>2y|7 zrVDdjX@IpbbX`(1GBs4C0EpXcHHBDGu-Bhf*6xw+O zt{ZK(00+*mocdxchmWY4V}`2Hd1?q|o?sVc!CtAOt;Y<(pq2D9NQmL^ESg`_IYm4q zWT0L^UVmr4hy(I#>e7_oUX&g6B~(W!Wfip#qv7B#vgoja~txch}H zwSfP00Bcj4prj8{Ma^2a&IX6g%8hf%lA0g2IfpGIs)~}2@*==+0KDnErmItJvZ}7+ zR%Z&jl@7`d2Vb97(lfRbl`3^@D7kvE36Ta6KO4%0S;(h_iqj55FOzoMNJgi3M$M)q zg{J3}vyx$LP4m{GsMMj+V}`IIDVe;UC8U2`&3aiC1$kN&)tq7!zN|XAu_1r2;m(_@ zOQw0%tRKW#L8KMe4>2c~8|0`>b-+qa_vnnOXH`A9;Pf-O(Y54ZRo+~Q;?f*CVh+z8 zB)3p2wOe{txXcQokghmA$BVA07564_lx9_fR@QuwkT)D*5D;A{>qCdhFQvresw(Gm z&OoqesaqAq6>4l48$fCp&pNDybCep|x>=5HrAkPYkl>=J-CZfT&}{Zt)YPn`(^G;W zE>|8oZ70>WImMuwBFOp{A|+(!g+{o>p9=xcv#=Hx=6yW`{4oUF3IUB_U^2{55}XqcgaIK8th3Nj z7FvBN3_KAA{u&075eB}S^I47n8Vj2&J3)K60-i9zSeu~=&1XOBt7=#<4+E4G0YLSBdz7l7S#kdSK;XZCWn zmM6v=oz<&F9NB%^MvhEcsQVqLn8SG5`cu+J#tR(?67q-xT$h*JZ@XJk+!{WK2zf`#>SiZ|lG`*C2Tg@F!m(76_1p#{jY z(9dwthg*PewE)kt&~Yx2R<{&64=wA;sM5^H5LNTDDhO z9HqOSKR6s$SE!;_;8=dS-^H;ySEk&IZ`aEE=4H?MqAXFxI4#*thQ{`e7*>MGN{TVE z$5IWn7FFx5BuKSYK{M7FIZsiizIa$3`78tT>gGjAe!DaO3lcKvXdz^5B)XYpK~bo@ zNzWs0&nKq#S;~6lz6Tw?PfYE-yZ1l1oA+!?1X6-dts4kt%XOjrCdxbyl-fN0;%L)r z?cUr76^;`ey+nZ#6)Lzx3=-mNb6lEGC9SSysbc7#i1uh1ZFU2xNc$7;?L-Cr_N`JS zEh!o20=?kid(R4Tj&7RzVhQR;CypC!!24}*ohjZ4+yUI% z0T>;?vmL-|9l(tapth5t$IDjZZ6%A|!p1k=3G8JBJGuSwbDh8<3+v@zVkaQ6u)(tK zjYUY(c8|Ty*tnx9#hZwbZkxy5LpX`G*7~U<Scd^I{&#uAl^04?weo}WJ581 zo-UnK_e}09`DSLOEHh^ocfi6oBU9`lej}AHnyGw-rPUQ^lVdEg(MeoXHN#N{7S3-~b$ z3v&;PSG#~ebpe0x0;ZC{<4NG1BydkRL+#?IC%b_!bpv`gaHSjQ?g7s90I&5h)Eyl4 zogUzN4{*B&nCk^D_W~dE0*gBs>d;+pL-H>u{53>*oHr*J=DSP&_A^MxnH`Ru(tPV; z3+4>;N#x&_m$J)&c{1!sWLS7nZtx0I%jAC1FY25o;wP0es;V3EXA=#`WeSa z`_HS?bq^gR^X%sjvJ@%=T^1#HTY87fa8CpZH$v1Af^D-0lPBcLLws3B0}& zi1ag=GRfT!W%_|^KXADpxY-Yk4KS2$E-#-O0KPr|{CWV03o5!whv7*V;dZfm_4C?h#;p z1bAhHp$u~y2lvXwU-MS{%2h(5%qv%^du8{-t>ad?;wLI6x6H$>>*Cs_kSuvAUGYx_ zN~>@lb=o3#z6)pXKw7N#@vV9mce6Qg?@}PFwBm%Da1(ZJLy{{SgWU(;5P48XRLnDT!0J1VUTzk0gbDU>YcG19e-9 zaZ4H-3ayKw4bAT9_I77ZXPpyL3i1!5yZ3pXd1vOGcix$~7Z)N42kDgb5Hk)O2)}0Ny#1*l&nlk zu*OMQra7A3n=);TM$1tus#=z6>mWu5IYfYxIV9+36>(ZtS1i*-hbbs73X*cLkg+U( zb6Hfy&;-%2EL%NgOQWiZi&Qr>!H`tNGM{po>rSgHx;cuCFMEI=c!0lqfIVJ7_X4kZ z0dE~JR0n*a4){(T@J1bQs}2bHn346kM>a_6Kjj0aeZZG}z>j^vO&kr^<^+2v3c&Q$^RS)zvFw~t~lr=CB(lMFMOUh(v zu4@gjc80D?N=~MRs+0h2HrtJ4bmIFY(@RNJYV{yFT~I9Iab-mlmY3HR>n?>ZUV-aI zr!ByNiz}z09Lup;HFwNVHF}5|f|)1SMOm`f>S)I?LojG9{frP|I6R9N*K|P<4+uG` zJt{0wO}9|z9jGQ7H7!VTL8C>;6(?jtR#&D~?MT58)jU1H&1a}!d3i`!E`5`*U0b2T z(jj5l8UiaO!|VV}t>%|n2dLR5aue8O^QN51>z9sBwPmQdxP4+yqYKiRdDX%l7V^{r z{>uRjXEZ^{?x%{Hw`@I)4x5!5XOsoCIBGKvTU1mPr5NR9fZ+i6vPDf-r#fX-T`DY3 zm2_(zltBkypH#9_wiC4~^{y(pda(|XMvx#I%B5K-riGf*4nwb!cHBrtXJAUrXC#GY zXOz>DVQo!^tVL0)LtBp-!jh!qih7oi{$Vv6WK|U8Nl{b_ic$K~dt!A%{&wTqo2yHv zb=j;R#A!jKHP;UbCzl)KxJ`AyDo*#-DOJy_dg_SN&(vzyQU_IeeI<%Zb9B}mo;4&N zpjPU#^sI217DORib9!zoyQ0?Io8(cNR}ETQ^ASR>JHj9&x>D9Xhbbs!#CcVfi#ca= zq-?2Q7Q`iLtQs3Z{ETPa*1|bT4ehL1jy_10kgOoVMN^l%QgET!>@laQc}b^_3Wm5? zd*pPUP*-LYgKCN(>kkkq39H@Xh9s|NO-Beh;u!Bv&Dk+#4-FDeJ_6_wrjGM6C1BC& zo76PnEU7E~6^%x1TZ!qb$Shg?Y-#De5CNWx0M}R-f-KbYmk4m1g@ri9WEAL+0(+wj zG|WMdM}f~rfu~t$6W926qrepw*3QCwZ$^QiM}a$0pgsnqV+ICiL3V6Zm|@TFiddS9P#p9tP$Ya;heY z%tsa^T4}nRPpprNX024AV5%F95sg2q8C`oY~9O zT9FuQc2=(zF}?kyjZE*bP@i_75)R`@>rY8fZ!2{mLda7NaM{l~%XZaaYtGVTRhNuO zv(%GmPB4mT_4f`;eO_3it9y=R4751T0j6=*v4Goya6fhbLM{$Leh>FqQ+{Xn_3hUh05#n zyvgnP#LhjIvRu3G5r^*+J9ppT`)BXxJsT6DjG$BN>VetAT&SRlG7kckHjm#p+Vol5 zHa9}0a|B1PP+7!<8ZHkbgrL)LTSAqrx{{}gp?@UW!&S7|4WuURkHELXHS{~MOqHyp zAMTH<0fJ zE_MUgx`A8WfVYRCw^c2}J1bVZrHya22N-7sd$|2^st1^1VFMiO@g5+9cv<1%#6rw$@KQA%!06xy%0ieDQOIK)i3B-7~=^$i{N|JXtxZ z?%J`Z;$xYavdo-W-T_PBq<6BX_tjKBXQuKgmR4V)?HFf?%}(N+su_+tz_4p~cOJGL z-%6{|Jes-BTg&TGVfPL9dOuAyT`HH+0ZG&+##c`~_n#AH*WR|S8F6mW+txWB_P}o2 z!8THTM(l|k|Nozl;tBMPo^m=S;||07YZ>y-b>D!7ucEt&ZmHPQoznWhT6+fkMse@`vAEQc)btk><7et;95UJ9ptF*^aFqF z2k!O*`v!o^1HkP8U}lh^j^6hgr1*5gpX;mRdgbGftAg`k2VA05ny@*cxD8+KEhCkxYh;2Tl4c)1&J!pTb1sW-7mI|TjiSHrkva=FSf3WYnMW*;-z%WzZIyg!g!SY&fbBvTMy$8>RFqc&3V*nlU+de`guh%7PFeLGOr$^Le10E&d{s;fWeL2h~bSG x-iYCi7~Y8C|7{FYS;$cNOtSQY=Tt_><%Aqf2@3|*Qq~W~{|hzvK@vwU005j3EbssT diff --git a/packages/orchestration/test/exos/chain-hub.test.ts b/packages/orchestration/test/exos/chain-hub.test.ts index 53a12302491..1a8efc8e762 100644 --- a/packages/orchestration/test/exos/chain-hub.test.ts +++ b/packages/orchestration/test/exos/chain-hub.test.ts @@ -86,28 +86,28 @@ test('denom info support via getAsset and getDenom', async t => { const denom = 'utok1'; const info1: CosmosChainInfo = { bech32Prefix: 'chain', - chainId: 'chain1', + chainId: 'agoric', stakingTokens: [{ denom }], }; const tok1 = withAmountUtils(makeIssuerKit('Tok1')); - chainHub.registerChain('chain1', info1); + chainHub.registerChain('agoric', info1); const info = { - chainName: 'chain1', - baseName: 'chain1', + chainName: 'agoric', + baseName: 'agoric', baseDenom: denom, brand: tok1.brand, }; chainHub.registerAsset('utok1', info); t.deepEqual( - chainHub.getAsset('utok1'), + chainHub.getAsset('utok1', 'agoric'), info, 'getAsset(denom) returns denom info', ); t.is( - chainHub.getAsset('utok404'), + chainHub.getAsset('utok404', 'agoric'), undefined, 'getAsset returns undefined when denom not registered', ); @@ -145,7 +145,7 @@ test('toward asset info in agoricNames (#9572)', async t => { registerAssets(chainHub, 'cosmoshub', details); { - const actual = chainHub.getAsset('uatom'); + const actual = chainHub.getAsset('uatom', 'cosmoshub'); t.deepEqual(actual, { chainName: 'cosmoshub', baseName: 'cosmoshub', @@ -156,6 +156,7 @@ test('toward asset info in agoricNames (#9572)', async t => { { const actual = chainHub.getAsset( 'ibc/F04D72CF9B5D9C849BB278B691CDFA2241813327430EC9CDC83F8F4CA4CDC2B0', + 'cosmoshub', ); t.deepEqual(actual, { chainName: 'cosmoshub', @@ -432,7 +433,7 @@ test('makeTransferRoute - no asset info', t => { ), { message: - 'no denom detail for: "uist". ensure it is registered in chainHub.', + 'no denom detail for: "uist" on "agoric". ensure it is registered in chainHub.', }, ); @@ -445,7 +446,7 @@ test('makeTransferRoute - no asset info', t => { ), { message: - 'no denom detail for: "ibc/FE98AAD68F02F03565E9FA39A5E627946699B2B07115889ED812D8BA639576A9". ensure it is registered in chainHub.', + 'no denom detail for: "ibc/FE98AAD68F02F03565E9FA39A5E627946699B2B07115889ED812D8BA639576A9" on "agoric". ensure it is registered in chainHub.', }, ); }); @@ -539,7 +540,7 @@ test('makeTransferRoute - asset not on holding chain', t => { ), { message: - 'cannot transfer asset "ibc/FE98AAD68F02F03565E9FA39A5E627946699B2B07115889ED812D8BA639576A9". held on "agoric" not "osmosis".', + 'no denom detail for: "ibc/FE98AAD68F02F03565E9FA39A5E627946699B2B07115889ED812D8BA639576A9" on "osmosis". ensure it is registered in chainHub.', }, ); }); diff --git a/packages/orchestration/test/facade-durability.test.ts b/packages/orchestration/test/facade-durability.test.ts index e6c3a4fe9ac..dff35064c26 100644 --- a/packages/orchestration/test/facade-durability.test.ts +++ b/packages/orchestration/test/facade-durability.test.ts @@ -184,7 +184,7 @@ test('asset / denom info', async t => { const { chainHub, orchestrate } = orchKit; chainHub.registerChain('agoric', fetchedChainInfo.agoric); - chainHub.registerChain(mockChainInfo.chainId, mockChainInfo); + chainHub.registerChain('mock', mockChainInfo); chainHub.registerConnection( 'agoric-3', mockChainInfo.chainId, @@ -192,8 +192,8 @@ test('asset / denom info', async t => { ); chainHub.registerAsset('utoken1', { - chainName: mockChainInfo.chainId, - baseName: mockChainInfo.chainId, + chainName: 'mock', + baseName: 'mock', baseDenom: 'utoken1', }); @@ -203,7 +203,7 @@ test('asset / denom info', async t => { t.log(`utoken1 over ${channelId}: ${agDenom}`); chainHub.registerAsset(agDenom, { chainName: 'agoric', - baseName: mockChainInfo.chainId, + baseName: 'mock', baseDenom: 'utoken1', brand, }); @@ -213,10 +213,14 @@ test('asset / denom info', async t => { { brand }, // eslint-disable-next-line no-shadow async (orc, { brand }) => { - const c1 = await orc.getChain(mockChainInfo.chainId); + const c1 = await orc.getChain('mock'); { - const actual = orc.getDenomInfo('utoken1'); + const actual = orc.getDenomInfo( + 'utoken1', + // @ts-expect-error 'mock' not a KnownChain + 'mock', + ); console.log('actual', actual); const info = await actual.chain.getChainInfo(); t.deepEqual(info, mockChainInfo); @@ -230,12 +234,12 @@ test('asset / denom info', async t => { } const agP = orc.getChain('agoric'); - t.throws(() => orc.getDenomInfo(agDenom), { + t.throws(() => orc.getDenomInfo(agDenom, 'agoric'), { message: /^wait until getChain\("agoric"\) completes/, }); const ag = await agP; { - const actual = orc.getDenomInfo(agDenom); + const actual = orc.getDenomInfo(agDenom, 'agoric'); t.deepEqual(actual, { chain: ag, @@ -258,7 +262,11 @@ test('asset / denom info', async t => { }); const missingGetChain = orchestrate('missing getChain', {}, async orc => { - const actual = orc.getDenomInfo('utoken2'); + const actual = orc.getDenomInfo( + 'utoken2', + // @ts-expect-error 'mock' not a KnownChain + 'anotherChain', + ); }); await t.throwsAsync(vt.when(missingGetChain()), { diff --git a/packages/orchestration/test/supports.ts b/packages/orchestration/test/supports.ts index dbf539c0919..6486a7ffbaa 100644 --- a/packages/orchestration/test/supports.ts +++ b/packages/orchestration/test/supports.ts @@ -174,7 +174,7 @@ export const commonSetup = async (t: ExecutionContext) => { * ChainHub. Use `ChainHubAdmin` instead. */ const registerAgoricBld = () => { - if (!chainHub.getAsset('ubld')) { + if (!chainHub.getAsset('ubld', 'agoric')) { chainHub.registerChain('agoric', fetchedChainInfo.agoric); chainHub.registerAsset('ubld', { chainName: 'agoric', diff --git a/packages/orchestration/test/types.test-d.ts b/packages/orchestration/test/types.test-d.ts index a889ca536e6..0b13a42fc19 100644 --- a/packages/orchestration/test/types.test-d.ts +++ b/packages/orchestration/test/types.test-d.ts @@ -110,7 +110,7 @@ expectNotType(chainAddr); expectNotType<() => Promise>(vowFn); const getDenomInfo: HostOf = null as any; - const chainHostOf = getDenomInfo('uatom').chain; + const chainHostOf = getDenomInfo('uatom', 'cosmoshub').chain; expectType>(chainHostOf.getChainInfo()); }