diff --git a/.gitignore b/.gitignore index 38dba46527a..57152254936 100644 --- a/.gitignore +++ b/.gitignore @@ -84,3 +84,5 @@ endo-sha.txt .aider* !.aiderignore +startElys-plan.json +testing/startElys.js diff --git a/packages/builders/scripts/testing/init-elys-contract.js b/packages/builders/scripts/testing/init-elys-contract.js index 4c6c8cd62d8..825efc12ff8 100644 --- a/packages/builders/scripts/testing/init-elys-contract.js +++ b/packages/builders/scripts/testing/init-elys-contract.js @@ -9,10 +9,7 @@ import { getManifest, startElys, } from '@agoric/orchestration/src/proposals/start-elys.js'; -// import { minimalChainInfos } from '../tools/chainInfo.js'; -// import { minimalChainInfos } from '../../../boot/test/tools/chainInfo.js'; -// import { assetOn } from '@agoric/orchestration/src/utils/asset.js'; -// import { parseArgs } from 'node:util'; + /** * @import {ParseArgsConfig} from 'node:util' @@ -34,6 +31,7 @@ export const minimalChainInfos = { cosmoshub: fetchedChainInfo.cosmoshub, stride: fetchedChainInfo.stride, elys: fetchedChainInfo.elys, + celestia: fetchedChainInfo.celestia, }; export const createFeeTestConfig = (feeCollector) => { @@ -131,13 +129,37 @@ export default async (homeP, endowments) => { }, ], [ - 'ibc/89BB00177EBDF554BF8382094D770DC3EA1C7F5945A48D61C07A867C6ED6709B', + 'utia', + { + baseDenom: 'utia', + baseName: 'celestia', + chainName: 'celestia', + }, + ], + [ + 'ibc/627650D6C650F179DDBD708591E613345910985F5549DB1F6991020B101EE8E0', { - baseDenom: 'ibc/EF3BDB6C8222A465BF8EC6B02EBE350E82DC0AC4FDB75286A92B8433A3B026EC', + baseDenom: 'ibc/D02B2CC73ABD49D2746AF67980F7CDD93A54B0AFF8C75EFA095B0423B8950653', baseName: 'elys', chainName: 'agoric', }, ], + [ + 'ibc/F00782820450D9F76025F7FC25BF026EC11309069CE89C1CD326311033E17E3E', + { + baseDenom: 'uatom', + baseName: 'cosmoshub', + chainName: 'agoric', + }, + ], + [ + 'ibc/510D1969E876B0DCE9EE450CEC7BF987164CF9E4E42516FF972EDDBA9B64BE09', + { + baseDenom: 'utia', + baseName: 'celestia', + chainName: 'agoric', + }, + ], ]); const parseChainInfo = () => { diff --git a/packages/builders/scripts/testing/startElys-plan.json b/packages/builders/scripts/testing/startElys-plan.json index 334782709fd..1c228598d84 100644 --- a/packages/builders/scripts/testing/startElys-plan.json +++ b/packages/builders/scripts/testing/startElys-plan.json @@ -5,13 +5,13 @@ "bundles": [ { "entrypoint": "@agoric/orchestration/src/examples/elys.contract.js", - "bundleID": "b1-e8757070250ee146430feaa37028364d186d7b8e7658c109934af159e957e2582b77315d04633e71fc476cdebca7edaf062011f3f8f613433e36b985f48947cb", - "fileName": "/home/adarsh/.agoric/cache/b1-e8757070250ee146430feaa37028364d186d7b8e7658c109934af159e957e2582b77315d04633e71fc476cdebca7edaf062011f3f8f613433e36b985f48947cb.json" + "bundleID": "b1-1ba3f11612ae100e8e92ffb12ac4baf3ac3db36617d945c37e57d1cccf73e5da7218399d919752de620ef427315e831fd2254b67d177dea308d126bb9cb05c57", + "fileName": "/Users/lupin/.agoric/cache/b1-1ba3f11612ae100e8e92ffb12ac4baf3ac3db36617d945c37e57d1cccf73e5da7218399d919752de620ef427315e831fd2254b67d177dea308d126bb9cb05c57.json" }, { "entrypoint": "@agoric/orchestration/src/proposals/start-elys.js", - "bundleID": "b1-039e04dafa79c7d7f705b7512a357f0b28b0dc889cc07c99a61ab66bd4ec76d76ff17c11ba1dd1b3868f503e1fb27c33f763bac042667ef551bf5cf5615be896", - "fileName": "/home/adarsh/.agoric/cache/b1-039e04dafa79c7d7f705b7512a357f0b28b0dc889cc07c99a61ab66bd4ec76d76ff17c11ba1dd1b3868f503e1fb27c33f763bac042667ef551bf5cf5615be896.json" + "bundleID": "b1-46f5117aab7daed52816a35bafbfac6da532d8f4cd380781299dc2652c3e3b2b87f47cda30c9781c6b830152c40513bc62ae1df30bae06c67faf76aca2f0a8bf", + "fileName": "/Users/lupin/.agoric/cache/b1-46f5117aab7daed52816a35bafbfac6da532d8f4cd380781299dc2652c3e3b2b87f47cda30c9781c6b830152c40513bc62ae1df30bae06c67faf76aca2f0a8bf.json" } ] } diff --git a/packages/builders/scripts/testing/startElys.js b/packages/builders/scripts/testing/startElys.js index fac8c48c4c7..8a3ed9d5ef0 100644 --- a/packages/builders/scripts/testing/startElys.js +++ b/packages/builders/scripts/testing/startElys.js @@ -1,13 +1,13 @@ // This is generated by writeCoreEval; please edit! /* eslint-disable */ -const manifestBundleRef = {bundleID:"b1-039e04dafa79c7d7f705b7512a357f0b28b0dc889cc07c99a61ab66bd4ec76d76ff17c11ba1dd1b3868f503e1fb27c33f763bac042667ef551bf5cf5615be896"}; +const manifestBundleRef = {bundleID:"b1-46f5117aab7daed52816a35bafbfac6da532d8f4cd380781299dc2652c3e3b2b87f47cda30c9781c6b830152c40513bc62ae1df30bae06c67faf76aca2f0a8bf"}; const getManifestCall = harden([ "getManifest", { installKeys: { ElysContract: { - bundleID: "b1-e8757070250ee146430feaa37028364d186d7b8e7658c109934af159e957e2582b77315d04633e71fc476cdebca7edaf062011f3f8f613433e36b985f48947cb", + bundleID: "b1-1ba3f11612ae100e8e92ffb12ac4baf3ac3db36617d945c37e57d1cccf73e5da7218399d919752de620ef427315e831fd2254b67d177dea308d126bb9cb05c57", }, }, options: { @@ -117,7 +117,7 @@ const getManifestCall = harden([ icqEnabled: false, namespace: "cosmos", pfmEnabled: true, - reference: "agoric-3", + reference: "agoricdev-25", stakingTokens: [ { denom: "ubld", @@ -169,7 +169,7 @@ const getManifestCall = harden([ icqEnabled: false, namespace: "cosmos", pfmEnabled: true, - reference: "cosmoshub-4", + reference: "provider", stakingTokens: [ { denom: "uatom", @@ -221,7 +221,7 @@ const getManifestCall = harden([ icqEnabled: false, namespace: "cosmos", pfmEnabled: false, - reference: "elys-1", + reference: "elysicstestnet-1", stakingTokens: [ { denom: "uelys", @@ -291,7 +291,7 @@ const getManifestCall = harden([ icqEnabled: false, namespace: "cosmos", pfmEnabled: true, - reference: "stride-1", + reference: "stride-internal-1", stakingTokens: [ { denom: "ustrd", diff --git a/packages/orchestration/src/examples/elys-contract.flows.js b/packages/orchestration/src/examples/elys-contract.flows.js index f4c8d9a05dd..9f29e39e44e 100644 --- a/packages/orchestration/src/examples/elys-contract.flows.js +++ b/packages/orchestration/src/examples/elys-contract.flows.js @@ -5,13 +5,18 @@ import { encodeBech32, } from '@agoric/cosmic-proto/address-hooks.js'; import { Any } from '@agoric/cosmic-proto/google/protobuf/any.js'; +// import { +// MsgLiquidStake, +// MsgLiquidStakeResponse, +// MsgRedeemStake, +// } from '@agoric/cosmic-proto/stride/stakeibc/tx.js'; import { MsgLiquidStake, MsgLiquidStakeResponse, MsgRedeemStake, -} from '@agoric/cosmic-proto/stride/stakeibc/tx.js'; +} from '@agoric/cosmic-proto/stride/staketia/tx.js'; import { tryDecodeResponse } from '../utils/cosmos.js'; -import { denomHash } from '../utils/denomHash.js'; +import { denomHash, denomHashFromPath } from '../utils/denomHash.js'; /** * @import {GuestInterface} from '@agoric/async-flow'; @@ -63,34 +68,66 @@ export const makeICAHookAccounts = async ( const agoric = await orch.getChain('agoric'); const { chainId: agoricChainId, bech32Prefix: agoricBech32Prefix } = await agoric.getChainInfo(); - trace('Creating local agoic account...'); + trace('Creating local Agoric account...'); const localAccount = await agoric.makeAccount(); const localAccountAddress = localAccount.getAddress(); + trace('Agoric local account Address: ', localAccountAddress); + + trace('Fetching Elys chainInfo...'); + // Elys ICA account + const elys = await orch.getChain('elys'); + const { chainId: elysChainId, bech32Prefix: elysBech32Prefix } = + await elys.getChainInfo(); + trace(`Elys chainId: ${elysChainId}`); + let elysICAAccount; + let elysICAAddress; + try { + trace('Creating Elys account on Elys...'); + elysICAAccount = await elys.makeAccount(); + elysICAAddress = elysICAAccount.getAddress(); + trace('Elys ICA created:', elysICAAddress); + } catch (err) { + trace('Failed to create Elys ICA account:', err); + throw err; + } trace('Fetching Stride chainInfo...'); // stride ICA account const stride = await orch.getChain('stride'); const { chainId: strideChainId, bech32Prefix: strideBech32Prefix } = await stride.getChainInfo(); - trace('Creating stride ICA account...'); + trace('Creating ICA account on Stride...'); const strideICAAccount = await stride.makeAccount(); const strideICAAddress = strideICAAccount.getAddress(); - - trace('Fetching Elys chainInfo...'); - // Elys ICA account - const elys = await orch.getChain('elys'); - const { chainId: elysChainId, bech32Prefix: elysBech32Prefix } = - await elys.getChainInfo(); - trace('Creating Elys ICA account...'); - - const elysICAAccount = await elys.makeAccount(); - const elysICAAddress = elysICAAccount.getAddress(); + trace( + '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Stride ICA Account Address: ', + strideICAAddress.value, + ); const { transferChannel: transferChannelAgoricElys } = await chainHub.getConnectionInfo(agoricChainId, elysChainId); const { transferChannel: transferChannelStrideElys } = await chainHub.getConnectionInfo(strideChainId, elysChainId); + trace('StrideElys channelId: ', transferChannelStrideElys.channelId); + trace('AgoricElys channelId: ', transferChannelAgoricElys.channelId); + + //TEST From Agoric local account transfer 1bld to elys1j3ut8walawveh8j0en2alyed983rfqqlef8600 + // const testReceiverAddress = { + // chainId: elysChainId, + // encoding: localAccountAddress.encoding, + // /** @type {`${string}1${string}`} */ + // value: 'elys1j3ut8walawveh8j0en2alyed983rfqqlef8600', + // }; + // localAccount.transfer(testReceiverAddress, { + // denom: 'ubld', + // value: 100000n, + // }); + + localAccount.getBalances().then(balances => { + trace('Local account balances: ', balances); + }); + trace('Connecting with all supported chanins...'); // ICA account on all the supported host chains for (const [_index, remoteChain] of allRemoteChains.entries()) { @@ -106,6 +143,7 @@ export const makeICAHookAccounts = async ( const ICAAccount = await remoteChain.makeAccount(); const ICAAddress = ICAAccount.getAddress(); + trace('Remote Chain ICA Account Address: ', ICAAddress.value); // get the connection info between agoric and remote chain const { transferChannel } = await chainHub.getConnectionInfo( @@ -113,17 +151,32 @@ export const makeICAHookAccounts = async ( chainId, ); const { transferChannel: transferChannelhostStride } = - await chainHub.getConnectionInfo(chainId, strideChainId); + await chainHub.getConnectionInfo(strideChainId, chainId); const ibcDenomOnAgoric = `ibc/${denomHash({ denom: nativeDenom, channelId: transferChannel.channelId })}`; const ibcDenomOnStride = `ibc/${denomHash({ denom: nativeDenom, channelId: transferChannelhostStride.channelId })}`; + trace('ibcDenomOnAgoric ', ibcDenomOnAgoric); + trace('nativeDenom ', nativeDenom); + trace('ibcDenomOnStride ', ibcDenomOnStride); + // Required in retrieving native token back from stTokens on elys chain - const stTokenDenomOnElys = `ibc/${denomHash({ denom: `st${nativeDenom}`, channelId: transferChannelStrideElys.channelId })}`; - stDenomOnElysTohostToAgoricChannelMap.init( - stTokenDenomOnElys, - transferChannel.counterPartyChannelId, - ); + let stTokenDenomOnElys = `ibc/${denomHash({ denom: `st${nativeDenom}`, channelId: transferChannelStrideElys.counterPartyChannelId })}`; + stTokenDenomOnElys = `transfer/${transferChannelStrideElys.counterPartyChannelId}/st${nativeDenom}`; + trace('stTokenDenomOnElys ', stTokenDenomOnElys); + //TODO: remove hardcoded value used here for debugging + + try { + stDenomOnElysTohostToAgoricChannelMap.init( + stTokenDenomOnElys, + transferChannel.counterPartyChannelId, + ); + } catch (error) { + trace( + `Error initializing stDenomOnElysTohostToAgoricChannelMap for ${stTokenDenomOnElys}:`, + error, + ); + } /** @type {SupportedHostChainShape} */ const hostChainInfo = { @@ -164,6 +217,7 @@ export const makeICAHookAccounts = async ( // @ts-expect-error tap.receiveUpcall: 'Vow | undefined' not assignable to 'Promise' await localAccount.monitorTransfers(tap); + trace('Done with makeICAHookAccounts++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'); return localAccount; }; harden(makeICAHookAccounts); @@ -208,11 +262,20 @@ export const tokenMovementAndStrideLSDFlow = async ( elysBech32Prefix, feeConfig, ) => { + trace( + 'tokenMovementAndStrideLSDFlow called with event:', + incomingIbcTransferEvent, + ); // Look for interested incoming tokens // Either supported chains Staking denoms or stTokens from elys chain const stakeToStride = supportedHostChains.has( incomingIbcTransferEvent.packet.source_channel, ); + trace(`stakeToStride: ${stakeToStride}`); + trace( + `packet source channel: ${incomingIbcTransferEvent.packet.source_channel}`, + ); + const redeemFromStride = incomingIbcTransferEvent.packet.source_channel === elysToAgoricChannel; if (!stakeToStride && !redeemFromStride) { @@ -234,6 +297,10 @@ export const tokenMovementAndStrideLSDFlow = async ( const senderStrideAddress = deriveAddress(tx.sender, strideBech32Prefix); const senderElysAddress = deriveAddress(tx.sender, elysBech32Prefix); + trace('senderAgoricAddress: ', senderAgoricAddress); + trace('senderStrideAddress: ', senderStrideAddress); + trace('senderElysAddress: ', senderElysAddress); + const senderAgoricChainAddress = { chainId: localAccountAddress.chainId, encoding: localAccountAddress.encoding, @@ -318,6 +385,7 @@ export const tokenMovementAndStrideLSDFlow = async ( denom: tx.denom, value: amountAfterFeeDeduction, }); + trace('Moved tokens to stride ICA account'); } catch (error) { await handleTransferFailure( hostChainInfo.hostICAAccount, @@ -364,13 +432,20 @@ export const tokenMovementAndStrideLSDFlow = async ( `Moving stTokens to elys from stride chain failed with error: ${error}, sending it to users wallet on stride chain`, ); } + trace(`Liquid stake on stride successful, stToken: ${stakingResponse.stToken.denom}, amount: ${stakingResponse.stToken.amount}`); + } else { + trace('Redeeming stTokens from Elys to Stride'); const hostToAgoricChannel = stDenomOnElysTohostToAgoricChannelMap.get( tx.denom, ); + trace(`hostToAgoricChannel for ${tx.denom} is ${hostToAgoricChannel}`); const hostChain = supportedHostChains.get(hostToAgoricChannel); + trace( + `hostChain for ${tx.denom} is ${hostChain.hostICAAccountAddress.chainId}`, + ); let incomingStTokenAmount; try { incomingStTokenAmount = BigInt(tx.amount); @@ -379,7 +454,8 @@ export const tokenMovementAndStrideLSDFlow = async ( return; } - const ibcDenomOnAgoricFromElys = `ibc/${denomHash({ denom: `${tx.denom}`, channelId: AgoricToElysChannel })}`; + trace(AgoricToElysChannel); + const ibcDenomOnAgoricFromElys = `ibc/${denomHash({ denom: tx.denom, channelId: AgoricToElysChannel })}`; trace(`LiquidStakeRedeem: Received ${tx.denom}`); trace(`LiquidStakeRedeem: Moving ${ibcDenomOnAgoricFromElys} to elys ICA`); @@ -418,7 +494,7 @@ export const tokenMovementAndStrideLSDFlow = async ( // Transfer to stride from elys ICA try { await elysICAAccount.transfer(strideICAAddress, { - denom: tx.denom, + denom: `ibc/${denomHashFromPath(tx.denom)}`, value: amountAfterFeeDeduction, }); } catch (error) { @@ -444,7 +520,7 @@ export const tokenMovementAndStrideLSDFlow = async ( await redeemOnStride( strideICAAccount, strideICAAddress, - tx.amount, + `${amountAfterFeeDeduction}`, hostChain.hostICAAccountAddress.chainId, senderNativeAddress, ); @@ -457,6 +533,9 @@ export const tokenMovementAndStrideLSDFlow = async ( `Unstaking on stride failed with error: ${error}, sending it to users wallet on stride chain`, ); } + trace( + `Redeem on stride successful, stToken: st${hostChain.nativeDenom}, amount: ${tx.amount}`, + ); } }; harden(tokenMovementAndStrideLSDFlow); @@ -489,6 +568,9 @@ const handleTransferFailure = async ( try { await account.send(address, { denom, value: amount }); + trace( + `Sent tokens to ${address.value}, denom: ${denom}, amount: ${amount}`, + ); } catch (error) { trace( `Failed to send tokens to ${address.value}, denom: ${denom}, amount: ${amount}`, @@ -534,15 +616,48 @@ const liquidStakeOnStride = async ( amount, denom, ) => { + // amount = 1000n; + // denom = 'utia'; + + trace('Calling liquid stake with parameters:'); + trace( + '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++strideICAAddress: ', + strideICAAddress.value, + ); + trace('amount: ', amount.toString()); + trace('denom: ', denom); + const strideLiquidStakeMsg = Any.toJSON( MsgLiquidStake.toProtoMsg({ - creator: strideICAAddress.value, - amount: amount.toString(), - hostDenom: denom, + staker: strideICAAddress.value, + nativeAmount: amount.toString(), + // hostDenom: denom, }), ); trace('Calling liquid stake'); + + /** Last error, if we run out of retries */ + let lastErr; + + for (let attempt = 1; attempt <= 20; attempt += 1) { + try { + trace(`Liquid-stake attempt ${attempt}/20`); + const resp = await strideICAAccount.executeEncodedTx([ + strideLiquidStakeMsg, + ]); + trace('Liquid stake response: ', resp); + return harden( + tryDecodeResponse(resp, MsgLiquidStakeResponse.fromProtoMsg), + ); + } catch (err) { + trace(`Attempt ${attempt} failed:`, err); + lastErr = err; + } + } + // All retries exhausted + throw Fail`Liquid stake failed after 200 attempts: ${lastErr}`; + const stakingResponse = await strideICAAccount.executeEncodedTx([ strideLiquidStakeMsg, ]); @@ -585,11 +700,17 @@ const redeemOnStride = async ( hostZone, receiver, ) => { + trace('Redeeming stake on stride'); + trace('strideICAAddress: ', strideICAAddress.value); + trace('amount: ', amount); + trace('hostZone: ', hostZone); + trace('receiver: ', receiver); + const strideRedeemStakeMsg = Any.toJSON( MsgRedeemStake.toProtoMsg({ - creator: strideICAAddress.value, - amount, - hostZone, + redeemer: strideICAAddress.value, + stTokenAmount: amount, + // hostZone, receiver, }), ); @@ -597,7 +718,8 @@ const redeemOnStride = async ( // https://github.com/Agoric/agoric-sdk/wiki/No-Nested-Await await null; - await strideICAAccount.executeEncodedTx([strideRedeemStakeMsg]); + const redeemResponse = await strideICAAccount.executeEncodedTx([strideRedeemStakeMsg]); + trace(`Redeem stake on stride executed successfully ${redeemResponse}`); }; harden(redeemOnStride); @@ -647,14 +769,14 @@ const deductedFeeAmount = async ( return harden(finalAmount); }; - /** * Splits a string into two halves at the first occurrence of '1'. + * * @param {string} input * @returns {Bech32Address} */ const convertToBech32Address = input => { const index = input.indexOf('1'); - return `${input.slice(0, index)}1${input.slice(index + 1)}` + return `${input.slice(0, index)}1${input.slice(index + 1)}`; }; -harden(convertToBech32Address); \ No newline at end of file +harden(convertToBech32Address); diff --git a/packages/orchestration/src/fetched-chain-info.js b/packages/orchestration/src/fetched-chain-info.js index b2cee293697..c10fef64664 100644 --- a/packages/orchestration/src/fetched-chain-info.js +++ b/packages/orchestration/src/fetched-chain-info.js @@ -12,6 +12,24 @@ export default /** @type {const} } */ ({ }, ], connections: { + 'mocha-4': { + id: 'connection-18', + client_id: '07-tendermint-21', + counterparty: { + client_id: '07-tendermint-21', + connection_id: 'connection-662', + }, + state: 3, + transferChannel: { + channelId: 'channel-129', + portId: 'transfer', + counterPartyChannelId: 'channel-399', + counterPartyPortId: 'transfer', + ordering: 0, + state: 3, + version: 'ics20-1', + }, + }, 'elysicstestnet-1': { id: 'connection-16', client_id: '07-tendermint-16', @@ -234,6 +252,76 @@ export default /** @type {const} } */ ({ version: 'ics20-1', }, }, + 'mocha-4': { + id: 'connection-281', + client_id: '07-tendermint-367', + counterparty: { + client_id: '07-tendermint-367', + connection_id: 'connection-26', + }, + state: 3, + transferChannel: { + channelId: 'channel-38', + portId: 'transfer', + counterPartyChannelId: 'channel-78', + counterPartyPortId: 'transfer', + ordering: 0, + state: 3, + version: 'ics20-1', + }, + }, + }, + }, + celestia: { + bech32Prefix: 'celestia', + chainId: 'mocha-4', + icqEnabled: false, + namespace: 'cosmos', + reference: 'mocha-4', + stakingTokens: [ + { + denom: 'utia', + }, + ], + connections: { + 'agoricdev-25': { + id: 'connection-18', + client_id: '07-tendermint-21', + counterparty: { + client_id: '07-tendermint-21', + connection_id: 'connection-662', + }, + state: 3, + transferChannel: { + channelId: 'channel-129', + portId: 'transfer', + counterPartyChannelId: 'channel-399', + counterPartyPortId: 'transfer', + ordering: 0, + state: 3, + version: 'ics20-1', + }, + }, + 'stride-internal-1': { + id: 'connection-26', + client_id: '07-tendermint-367', + counterparty: { + client_id: '07-tendermint-367', + connection_id: 'connection-281', + }, + state: 3, + transferChannel: { + channelId: 'channel-78', + portId: 'transfer', + counterPartyChannelId: 'channel-38', + counterPartyPortId: 'transfer', + ordering: 0, + state: 3, + version: 'ics20-1', + }, }, + }, +}, + }); \ No newline at end of file diff --git a/packages/orchestration/src/proposals/start-elys.js b/packages/orchestration/src/proposals/start-elys.js index 2825f8fbf8e..a0d289977c6 100644 --- a/packages/orchestration/src/proposals/start-elys.js +++ b/packages/orchestration/src/proposals/start-elys.js @@ -65,7 +65,7 @@ export const startElys = async ( denominator: BigInt(100), }, // 10% }; - const allowedChains = ['cosmoshub']; + const allowedChains = ['cosmoshub', 'celestia']; /** @type {StartUpgradableOpts} */ const startOpts = { @@ -90,8 +90,11 @@ export const startElys = async ( }; const { instance, creatorFacet } = await E(startUpgradable)(startOpts); + trace('elys instance created'); const addressNode = await E(storageNode).makeChildNode('address'); + trace('elys address node created'); const address = await E(creatorFacet).getLocalAddress(); + trace('elys address fetched', address); await E(addressNode).setValue( JSON.stringify(address) ); produceInstance.resolve(instance); diff --git a/packages/orchestration/src/utils/denomHash.js b/packages/orchestration/src/utils/denomHash.js index 561ee4b512c..5b9059f9fde 100644 --- a/packages/orchestration/src/utils/denomHash.js +++ b/packages/orchestration/src/utils/denomHash.js @@ -20,3 +20,34 @@ export const denomHash = ({ const h = sha256.create().update(`${path}/${denom}`).digest(); return bytesToHex(h).toUpperCase(); }; + +/** + * Calculates denomHash from a full denomination path string + * + * @param {string} fullPath - String in format "${path}/${denom}" (e.g. "transfer/channel-1/utia") + * @returns {string} The hash of the denomination path + * @throws {Error} If the path format is invalid + */ +export const denomHashFromPath = (fullPath) => { + if (!fullPath || !fullPath.includes('/')) { + throw new Error('Invalid path format: expected "${path}/${denom}"'); + } + + const lastSlashIndex = fullPath.lastIndexOf('/'); + const path = fullPath.substring(0, lastSlashIndex); + const denom = fullPath.substring(lastSlashIndex + 1); + + if (!path || !denom) { + throw new Error('Invalid path format: path or denom component is empty'); + } + + return denomHash({ path, denom }); +}; +// Hardcoded values — to try one +// const stUtiaOnElys = denomHash({ denom: 'stutia', channelId: 'channel-12' }); +// const stUtiaOnAgoric = denomHash({ +// denom: `transfer/channel-12/stutia`, +// channelId: 'channel-23' +// }); +// console.log( stUtiaOnElys ); +// console.log( stUtiaOnAgoric );