From 481d84b9fe9db3adad0dcc6cc7cb5362e1a22a3b Mon Sep 17 00:00:00 2001 From: Milap Sheth Date: Tue, 24 Sep 2024 15:05:50 -0400 Subject: [PATCH 1/3] fix(sui): use new sui gateway send message for call contract (#389) --- sui/gateway.js | 13 ++++++++----- sui/utils/sign-utils.js | 4 +--- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/sui/gateway.js b/sui/gateway.js index 0313c81b..573b4a2a 100644 --- a/sui/gateway.js +++ b/sui/gateway.js @@ -116,8 +116,8 @@ async function callContract(keypair, client, config, chain, contractConfig, args }); } - tx.moveCall({ - target: `${packageId}::gateway::call_contract`, + const messageTicket = tx.moveCall({ + target: `${packageId}::gateway::prepare_message`, arguments: [ channel, tx.pure(bcs.string().serialize(destinationChain).toBytes()), @@ -126,6 +126,11 @@ async function callContract(keypair, client, config, chain, contractConfig, args ], }); + tx.moveCall({ + target: `${packageId}::gateway::send_message`, + arguments: [messageTicket], + }); + if (!options.channel) { tx.moveCall({ target: `${packageId}::channel::destroy`, @@ -133,9 +138,7 @@ async function callContract(keypair, client, config, chain, contractConfig, args }); } - await broadcast(client, keypair, tx); - - printInfo('Contract called'); + await broadcast(client, keypair, tx, 'Message sent'); } async function approveMessages(keypair, client, config, chain, contractConfig, args, options) { diff --git a/sui/utils/sign-utils.js b/sui/utils/sign-utils.js index af04024a..fb9ce366 100644 --- a/sui/utils/sign-utils.js +++ b/sui/utils/sign-utils.js @@ -110,9 +110,7 @@ async function broadcast(client, keypair, tx, actionName) { }, }); - if (actionName) { - printInfo(actionName, receipt.digest); - } + printInfo(actionName || 'Tx', receipt.digest); return receipt; } From bfb7595f0f7ad49e7406e78d17e0a03214fa87fb Mon Sep 17 00:00:00 2001 From: eguajardo Date: Tue, 24 Sep 2024 15:11:46 -0600 Subject: [PATCH 2/3] feat(amplifier)!: remove support for looping through multiple chains (#388) Co-authored-by: Talal Ashraf --- common/utils.js | 2 +- cosmwasm/cli-utils.js | 2 +- cosmwasm/deploy-contract.js | 40 ++++----- cosmwasm/submit-proposal.js | 162 +++++++++++++++--------------------- cosmwasm/utils.js | 47 ++++------- 5 files changed, 99 insertions(+), 154 deletions(-) diff --git a/common/utils.js b/common/utils.js index b49e3f35..86a4d862 100644 --- a/common/utils.js +++ b/common/utils.js @@ -410,7 +410,7 @@ async function getDomainSeparator(config, chain, options) { } const getChainConfig = (config, chainName) => { - if (chainName === 'none') { + if (!chainName) { return undefined; } diff --git a/cosmwasm/cli-utils.js b/cosmwasm/cli-utils.js index bc8b07ff..2ee62de2 100644 --- a/cosmwasm/cli-utils.js +++ b/cosmwasm/cli-utils.js @@ -68,7 +68,7 @@ const addAmplifierOptions = (program, options) => { const addContractOptions = (program) => { program.addOption(new Option('-c, --contractName ', 'contract name').makeOptionMandatory(true)); - program.addOption(new Option('-n, --chainNames ', 'chain names').default('none').env('CHAINS')); + program.addOption(new Option('-n, --chainName ', 'chain name').env('CHAIN')); }; const addStoreOptions = (program) => { diff --git a/cosmwasm/deploy-contract.js b/cosmwasm/deploy-contract.js index 479cb6b5..af7a2eea 100644 --- a/cosmwasm/deploy-contract.js +++ b/cosmwasm/deploy-contract.js @@ -11,7 +11,7 @@ const { prepareClient, fromHex, getSalt, - getChains, + getAmplifierContractConfig, updateContractConfig, fetchCodeIdFromCodeHash, uploadContract, @@ -22,14 +22,11 @@ const { const { Command, Option } = require('commander'); const { addAmplifierOptions } = require('./cli-utils'); -const upload = async (client, wallet, chainName, config, options) => { - const { reuseCodeId, contractName, fetchCodeId, instantiate2, salt, chainNames } = options; - const { - axelar: { - contracts: { [contractName]: contractConfig }, - }, - } = config; - const chainConfig = chainName === 'none' ? undefined : getChainConfig(config, chainName); +const upload = async (client, wallet, config, options) => { + const { reuseCodeId, contractName, fetchCodeId, instantiate2, salt, chainName } = options; + + const contractConfig = getAmplifierContractConfig(config, contractName); + const chainConfig = getChainConfig(config, chainName); if (!fetchCodeId && (!reuseCodeId || isNil(contractConfig.codeId))) { printInfo('Uploading contract binary'); @@ -41,7 +38,7 @@ const upload = async (client, wallet, chainName, config, options) => { if (instantiate2) { const [account] = await wallet.getAccounts(); - const address = instantiate2Address(fromHex(checksum), account.address, getSalt(salt, contractName, chainNames), 'axelar'); + const address = instantiate2Address(fromHex(checksum), account.address, getSalt(salt, contractName, chainName), 'axelar'); updateContractConfig(contractConfig, chainConfig, 'address', address); @@ -52,14 +49,11 @@ const upload = async (client, wallet, chainName, config, options) => { } }; -const instantiate = async (client, wallet, chainName, config, options) => { - const { contractName, fetchCodeId } = options; - const { - axelar: { - contracts: { [contractName]: contractConfig }, - }, - chains: { [chainName]: chainConfig }, - } = config; +const instantiate = async (client, wallet, config, options) => { + const { contractName, fetchCodeId, chainName } = options; + + const contractConfig = getAmplifierContractConfig(config, contractName); + const chainConfig = getChainConfig(config, chainName); if (fetchCodeId) { contractConfig.codeId = await fetchCodeIdFromCodeHash(client, contractConfig); @@ -72,24 +66,20 @@ const instantiate = async (client, wallet, chainName, config, options) => { updateContractConfig(contractConfig, chainConfig, 'address', contractAddress); - printInfo(`Instantiated ${chainName === 'none' ? '' : chainName.concat(' ')}${contractName}. Address`, contractAddress); + printInfo(`Instantiated ${chainName ? chainName.concat(' ') : ''}${contractName}. Address`, contractAddress); }; const main = async (options) => { const { env, uploadOnly, yes } = options; const config = loadConfig(env); - const chains = getChains(config, options); - const wallet = await prepareWallet(options); const client = await prepareClient(config, wallet); - await upload(client, wallet, chains[0], config, options); + await upload(client, wallet, config, options); if (!(uploadOnly || prompt(`Proceed with deployment on axelar?`, yes))) { - for (const chain of chains) { - await instantiate(client, wallet, chain.toLowerCase(), config, options); - } + await instantiate(client, wallet, config, options); } saveConfig(config, env); diff --git a/cosmwasm/submit-proposal.js b/cosmwasm/submit-proposal.js index a1f269e5..ad3364a0 100644 --- a/cosmwasm/submit-proposal.js +++ b/cosmwasm/submit-proposal.js @@ -12,7 +12,6 @@ const { fromHex, getSalt, readWasmFile, - getChains, getAmplifierContractConfig, updateContractConfig, fetchCodeIdFromCodeHash, @@ -41,18 +40,15 @@ const { ParameterChangeProposal } = require('cosmjs-types/cosmos/params/v1beta1/ const { Command } = require('commander'); const { addAmplifierOptions } = require('./cli-utils'); -const predictAndUpdateAddress = async (client, contractConfig, chainConfig, chainName, options) => { - const { contractName, salt, chainNames, runAs } = options; +const predictAndUpdateAddress = async (client, contractConfig, chainConfig, options) => { + const { contractName, salt, chainName, runAs } = options; const { checksum } = await client.getCodeDetails(contractConfig.codeId); - const contractAddress = instantiate2Address(fromHex(checksum), runAs, getSalt(salt, contractName, chainNames), 'axelar'); + const contractAddress = instantiate2Address(fromHex(checksum), runAs, getSalt(salt, contractName, chainName), 'axelar'); updateContractConfig(contractConfig, chainConfig, 'address', contractAddress); - printInfo( - `Predicted address for ${chainName.toLowerCase() === 'none' ? '' : chainName.toLowerCase().concat(' ')}${contractName}. Address`, - contractAddress, - ); + printInfo(`Predicted address for ${chainName ? chainName.concat(' ') : ''}${contractName}. Address`, contractAddress); }; const printProposal = (proposal, proposalType) => { @@ -96,100 +92,82 @@ const storeCode = async (client, wallet, config, options) => { }; const storeInstantiate = async (client, wallet, config, options) => { - const chains = getChains(config, options); - - for (const chain of chains) { - const chainName = chain.toLowerCase(); - - const { contractName, instantiate2 } = options; - const contractConfig = getAmplifierContractConfig(config, contractName); - const chainConfig = getChainConfig(config, chainName); + const { contractName, instantiate2, chainName } = options; + const contractConfig = getAmplifierContractConfig(config, contractName); + const chainConfig = getChainConfig(config, chainName); - if (instantiate2) { - throw new Error('instantiate2 not supported for storeInstantiate'); - } + if (instantiate2) { + throw new Error('instantiate2 not supported for storeInstantiate'); + } - const initMsg = makeInstantiateMsg(contractName, chainName, config); - const proposal = encodeStoreInstantiateProposal(config, options, initMsg); + const initMsg = makeInstantiateMsg(contractName, chainName, config); + const proposal = encodeStoreInstantiateProposal(config, options, initMsg); - if (!confirmProposalSubmission(options, proposal, StoreAndInstantiateContractProposal)) { - return; - } + if (!confirmProposalSubmission(options, proposal, StoreAndInstantiateContractProposal)) { + return; + } - const proposalId = await callSubmitProposal(client, wallet, config, options, proposal); + const proposalId = await callSubmitProposal(client, wallet, config, options, proposal); - updateContractConfig(contractConfig, chainConfig, 'storeInstantiateProposalId', proposalId); - contractConfig.storeCodeProposalCodeHash = createHash('sha256').update(readWasmFile(options)).digest().toString('hex'); - } + updateContractConfig(contractConfig, chainConfig, 'storeInstantiateProposalId', proposalId); + contractConfig.storeCodeProposalCodeHash = createHash('sha256').update(readWasmFile(options)).digest().toString('hex'); }; const instantiate = async (client, wallet, config, options) => { - const chains = getChains(config, options); - - for (const chain of chains) { - const chainName = chain.toLowerCase(); - - const { contractName, instantiate2, predictOnly, fetchCodeId } = options; - const contractConfig = getAmplifierContractConfig(config, contractName); - const chainConfig = getChainConfig(config, chainName); + const { contractName, instantiate2, predictOnly, fetchCodeId, chainName } = options; + const contractConfig = getAmplifierContractConfig(config, contractName); + const chainConfig = getChainConfig(config, chainName); - if (fetchCodeId) { - contractConfig.codeId = await fetchCodeIdFromCodeHash(client, contractConfig); - } else if (!isNumber(contractConfig.codeId)) { - throw new Error('Code Id is not defined'); - } + if (fetchCodeId) { + contractConfig.codeId = await fetchCodeIdFromCodeHash(client, contractConfig); + } else if (!isNumber(contractConfig.codeId)) { + throw new Error('Code Id is not defined'); + } - if (predictOnly) { - return predictAndUpdateAddress(client, contractConfig, chainConfig, chainName, options); - } + if (predictOnly) { + return predictAndUpdateAddress(client, contractConfig, chainConfig, options); + } - const initMsg = makeInstantiateMsg(contractName, chainName, config); + const initMsg = makeInstantiateMsg(contractName, chainName, config); - let proposal; - let proposalType; + let proposal; + let proposalType; - if (instantiate2) { - proposal = encodeInstantiate2Proposal(config, options, initMsg); - proposalType = InstantiateContract2Proposal; - } else { - proposal = encodeInstantiateProposal(config, options, initMsg); - proposalType = InstantiateContractProposal; - } + if (instantiate2) { + proposal = encodeInstantiate2Proposal(config, options, initMsg); + proposalType = InstantiateContract2Proposal; + } else { + proposal = encodeInstantiateProposal(config, options, initMsg); + proposalType = InstantiateContractProposal; + } - if (!confirmProposalSubmission(options, proposal, proposalType)) { - return; - } + if (!confirmProposalSubmission(options, proposal, proposalType)) { + return; + } - const proposalId = await callSubmitProposal(client, wallet, config, options, proposal); + const proposalId = await callSubmitProposal(client, wallet, config, options, proposal); - updateContractConfig(contractConfig, chainConfig, 'instantiateProposalId', proposalId); + updateContractConfig(contractConfig, chainConfig, 'instantiateProposalId', proposalId); - if (instantiate2) { - return predictAndUpdateAddress(client, contractConfig, chainConfig, chainName, options); - } + if (instantiate2) { + return predictAndUpdateAddress(client, contractConfig, chainConfig, options); } }; const execute = async (client, wallet, config, options) => { - const chains = getChains(config, options); - - for (const chain of chains) { - const chainName = chain.toLowerCase(); - - const { contractName } = options; - const contractConfig = getAmplifierContractConfig(config, contractName); - const chainConfig = getChainConfig(config, chainName); + const { contractName, chainName } = options; + const contractConfig = getAmplifierContractConfig(config, contractName); + const chainConfig = getChainConfig(config, chainName); - const proposal = encodeExecuteContractProposal(config, options, chainName); + const proposal = encodeExecuteContractProposal(config, options, chainName); - if (!confirmProposalSubmission(options, proposal, ExecuteContractProposal)) { - return; - } + if (!confirmProposalSubmission(options, proposal, ExecuteContractProposal)) { + return; + } - const proposalId = await callSubmitProposal(client, wallet, config, options, proposal); + const proposalId = await callSubmitProposal(client, wallet, config, options, proposal); - updateContractConfig(contractConfig, chainConfig, 'executeProposalId', proposalId); - } + updateContractConfig(contractConfig, chainConfig, 'executeProposalId', proposalId); }; const paramChange = async (client, wallet, config, options) => { @@ -203,28 +181,22 @@ const paramChange = async (client, wallet, config, options) => { }; const migrate = async (client, wallet, config, options) => { - const chains = getChains(config, options); - - for (const chain of chains) { - const chainName = chain.toLowerCase(); - - const { contractName, fetchCodeId } = options; - const contractConfig = getAmplifierContractConfig(config, contractName); - - if (fetchCodeId) { - contractConfig.codeId = await fetchCodeIdFromCodeHash(client, contractConfig); - } else if (!isNumber(contractConfig.codeId)) { - throw new Error('Code Id is not defined'); - } + const { contractName, fetchCodeId, chainName } = options; + const contractConfig = getAmplifierContractConfig(config, contractName); - const proposal = encodeMigrateContractProposal(config, options, chainName); + if (fetchCodeId) { + contractConfig.codeId = await fetchCodeIdFromCodeHash(client, contractConfig); + } else if (!isNumber(contractConfig.codeId)) { + throw new Error('Code Id is not defined'); + } - if (!confirmProposalSubmission(options, proposal, MigrateContractProposal)) { - return; - } + const proposal = encodeMigrateContractProposal(config, options, chainName); - await callSubmitProposal(client, wallet, config, options, proposal); + if (!confirmProposalSubmission(options, proposal, MigrateContractProposal)) { + return; } + + await callSubmitProposal(client, wallet, config, options, proposal); }; const mainProcessor = async (processor, options) => { diff --git a/cosmwasm/utils.js b/cosmwasm/utils.js index 272e7b88..80c96de7 100644 --- a/cosmwasm/utils.js +++ b/cosmwasm/utils.js @@ -52,28 +52,12 @@ const isValidCosmosAddress = (str) => { const fromHex = (str) => new Uint8Array(Buffer.from(str.replace('0x', ''), 'hex')); -const getSalt = (salt, contractName, chainNames) => fromHex(getSaltFromKey(salt || contractName.concat(chainNames))); +const getSalt = (salt, contractName, chainName) => fromHex(getSaltFromKey(salt || contractName.concat(chainName))); const getLabel = ({ contractName, label }) => label || contractName; const readWasmFile = ({ artifactPath, contractName }) => readFileSync(`${artifactPath}/${pascalToSnake(contractName)}.wasm`); -const getChains = (config, { chainNames, instantiate2 }) => { - let chains = chainNames.split(',').map((str) => str.trim()); - - if (chainNames === 'all') { - chains = Object.keys(config.chains); - } - - if (chains.length !== 1 && instantiate2) { - throw new Error('Cannot pass --instantiate2 with more than one chain'); - } - - chains.every((chain) => chain === 'none' || getChainConfig(config, chain)); - - return chains; -}; - const getAmplifierContractConfig = (config, contractName) => { const contractConfig = config.axelar.contracts[contractName]; @@ -109,7 +93,7 @@ const uploadContract = async (client, wallet, config, options) => { }; const instantiateContract = async (client, wallet, initMsg, config, options) => { - const { contractName, salt, instantiate2, chainNames, admin } = options; + const { contractName, salt, instantiate2, chainName, admin } = options; const [account] = await wallet.getAccounts(); @@ -126,7 +110,7 @@ const instantiateContract = async (client, wallet, initMsg, config, options) => ? await client.instantiate2( account.address, contractConfig.codeId, - getSalt(salt, contractName, chainNames), + getSalt(salt, contractName, chainName), initMsg, contractLabel, initFee, @@ -479,7 +463,7 @@ const makeInstantiateMsg = (contractName, chainName, config) => { switch (contractName) { case 'Coordinator': { if (chainConfig) { - throw new Error('Coordinator does not support chainNames option'); + throw new Error('Coordinator does not support chainName option'); } return makeCoordinatorInstantiateMsg(contractConfig); @@ -487,7 +471,7 @@ const makeInstantiateMsg = (contractName, chainName, config) => { case 'ServiceRegistry': { if (chainConfig) { - throw new Error('ServiceRegistry does not support chainNames option'); + throw new Error('ServiceRegistry does not support chainName option'); } return makeServiceRegistryInstantiateMsg(contractConfig); @@ -495,7 +479,7 @@ const makeInstantiateMsg = (contractName, chainName, config) => { case 'Multisig': { if (chainConfig) { - throw new Error('Multisig does not support chainNames option'); + throw new Error('Multisig does not support chainName option'); } return makeMultisigInstantiateMsg(contractConfig, contracts); @@ -503,7 +487,7 @@ const makeInstantiateMsg = (contractName, chainName, config) => { case 'Rewards': { if (chainConfig) { - throw new Error('Rewards does not support chainNames option'); + throw new Error('Rewards does not support chainName option'); } return makeRewardsInstantiateMsg(contractConfig); @@ -511,7 +495,7 @@ const makeInstantiateMsg = (contractName, chainName, config) => { case 'Router': { if (chainConfig) { - throw new Error('Router does not support chainNames option'); + throw new Error('Router does not support chainName option'); } return makeRouterInstantiateMsg(contractConfig, contracts); @@ -519,7 +503,7 @@ const makeInstantiateMsg = (contractName, chainName, config) => { case 'NexusGateway': { if (chainConfig) { - throw new Error('NexusGateway does not support chainNames option'); + throw new Error('NexusGateway does not support chainName option'); } return makeNexusGatewayInstantiateMsg(contractConfig, contracts); @@ -527,7 +511,7 @@ const makeInstantiateMsg = (contractName, chainName, config) => { case 'VotingVerifier': { if (!chainConfig) { - throw new Error('VotingVerifier requires chainNames option'); + throw new Error('VotingVerifier requires chainName option'); } return makeVotingVerifierInstantiateMsg(contractConfig, contracts, chainConfig); @@ -535,7 +519,7 @@ const makeInstantiateMsg = (contractName, chainName, config) => { case 'Gateway': { if (!chainConfig) { - throw new Error('Gateway requires chainNames option'); + throw new Error('Gateway requires chainName option'); } return makeGatewayInstantiateMsg(contracts, chainConfig); @@ -543,7 +527,7 @@ const makeInstantiateMsg = (contractName, chainName, config) => { case 'MultisigProver': { if (!chainConfig) { - throw new Error('MultisigProver requires chainNames option'); + throw new Error('MultisigProver requires chainName option'); } return makeMultisigProverInstantiateMsg(config, chainName); @@ -551,7 +535,7 @@ const makeInstantiateMsg = (contractName, chainName, config) => { case 'AxelarnetGateway': { if (!chainConfig) { - throw new Error('AxelarnetGateway requires chainNames option'); + throw new Error('AxelarnetGateway requires chainName option'); } return makeAxelarnetGatewayInstantiateMsg(config, chainName); @@ -653,11 +637,11 @@ const getInstantiateContractParams = (config, options, msg) => { }; const getInstantiateContract2Params = (config, options, msg) => { - const { contractName, salt, chainNames } = options; + const { contractName, salt, chainName } = options; return { ...getInstantiateContractParams(config, options, msg), - salt: getSalt(salt, contractName, chainNames), + salt: getSalt(salt, contractName, chainName), }; }; @@ -810,7 +794,6 @@ module.exports = { getSalt, calculateDomainSeparator, readWasmFile, - getChains, getAmplifierContractConfig, updateContractConfig, uploadContract, From 1827193fbdeddd776f1af69a19e1dce18ec3a2bd Mon Sep 17 00:00:00 2001 From: npty <78221556+npty@users.noreply.github.com> Date: Wed, 25 Sep 2024 13:51:36 +0700 Subject: [PATCH 3/3] chore: remove continue-on-error since the issue is resolved (#390) --- .github/workflows/test-sui.yaml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/test-sui.yaml b/.github/workflows/test-sui.yaml index 5201e7fa..4286e804 100644 --- a/.github/workflows/test-sui.yaml +++ b/.github/workflows/test-sui.yaml @@ -141,7 +141,6 @@ jobs: run: node sui/gateway.js approve --proof wallet ethereum 0x32034b47cb29d162d9d803cc405356f4ac0ec07fe847ace431385fe8acf3e6e5-2 0x4F4495243837681061C4743b74B3eEdf548D56A5 0x6ce0d81b412abca2770eddb1549c9fcff721889c3aab1203dc93866db22ecc4b 0x56570de287d73cd1cb6092bb8fdee6173974955fdef345ae579ee9f475ea7432 - name: Gateway Call Contract - continue-on-error: true run: node sui/gateway.js call-contract ethereum 0x4F4495243837681061C4743b74B3eEdf548D56A5 0x1234 - name: Gateway Rotate Signers @@ -150,11 +149,9 @@ jobs: ###### Command: GMP ###### - name: Execute Outgoing Call Contract - continue-on-error: true run: node sui/gmp.js sendCall ethereum 0x6f24A47Fc8AE5441Eb47EFfC3665e70e69Ac3F05 0.1 0x1234 - name: Execute Incoming Call Contract - continue-on-error: true run: | channel_id=$(cat axelar-chains-config/info/local.json | jq '.sui.contracts.Example.objects.ChannelId' | sed 's/"//g') echo "Channel ID: $channel_id" @@ -238,7 +235,6 @@ jobs: && mv temp.json axelar-chains-config/info/local.json - name: Post Upgrade Gateway Approval With New Package ID - continue-on-error: true run: node sui/gateway.js approve --proof wallet ethereum 0x32034b47cb29d162d9d803cc405356f4ac0ec07fe847ace431385fe8acf3e6e5-10 0x4F4495243837681061C4743b74B3eEdf548D56A5 0x6ce0d81b412abca2770eddb1549c9fcff721889c3aab1203dc93866db22ecc4b 0x56570de287d73cd1cb6092bb8fdee6173974955fdef345ae579ee9f475ea7432 ###### Command: Transfer Object ######