diff --git a/cosmwasm/README.md b/cosmwasm/README.md index b32e9488..1e1cfeb7 100644 --- a/cosmwasm/README.md +++ b/cosmwasm/README.md @@ -112,21 +112,36 @@ This folder contains deployment scripts for cosmwasm contracts needed for amplif Deploy each contract. Chain name should match the key of an object in the `chains` section of the config. Chain name should be omitted for contracts that are not chain specific. - `node deploy-contract.js -m [mnemonic] -a [path to contract artifacts] -c [contract name] -e [environment] -n ` - -Some of the contracts depend on each other and need to be deployed in a specific order. Note the connection router and nexus gateway each need to know the other's address, so you need to pass `--instantiate2`, and upload each contract before instatiating (by passing `-u`). - -1. `node deploy-contract.js -m [mnemonic] -a [path to artifacts] -c "Router" --instantiate2 -e devnet -u` -2. `node deploy-contract.js -m [mnemonic] -a [path to artifacts] -c "NexusGateway" --instantiate2 -e devnet -u` -3. `node deploy-contract.js -m [mnemonic] -a [path to artifacts] -c "NexusGateway" --instantiate2 -e devnet -r` -4. `node deploy-contract.js -m [mnemonic] -a [path to artifacts] -c "Router" --instantiate2 -e devnet -r` -5. `node deploy-contract.js -m [mnemonic] -a [path to artifacts] -c "ServiceRegistry" -e devnet` -6. `node deploy-contract.js -m [mnemonic] -a [path to artifacts] -c "Rewards" -e devnet` -7. `node deploy-contract.js -m [mnemonic] -a [path to artifacts] -c "Coordinator" -e devnet` -8. `node deploy-contract.js -m [mnemonic] -a [path to artifacts] -c "Multisig" -e devnet` -9. `node deploy-contract.js -m [mnemonic] -a [path to artifacts] -c "VotingVerifier" -e devnet -n "ethereum,avalanche"` -10. `node deploy-contract.js -m [mnemonic] -a [path to artifacts] -c "Gateway" -e devnet -n "ethereum,avalanche"` -11. `node deploy-contract.js -m [mnemonic] -a [path to artifacts] -c "MultisigProver" -e devnet -n "ethereum,avalanche"` + `node deploy-contract.js [upload|instantiate|upload-instantiate] -m [mnemonic] -a [path to contract artifacts] -c [contract name] -e [environment] -n ` + +Available subcommands: + +- `upload`: Uploads wasm file and saves codeId to `lastUploadedCodeId` in config + +- `instantiate`: Instantiates a contract, it gets the codeId by order of priority from: + + 1. Value of `--codeId` option + 2. From the network when using `--fetchCodeId` option by comparing previously uploaded bytecode's code hash with config `storeCodeProposalCodeHash` + 3. Value of previously saved `lastUploadedCodeId` in config + +- `upload-instantiate`: Both uploads and then instantiates a contract using the code Id that was just created. It doesn't accept `--codeId` nor `--fetchCodeId` options + +Some of the contracts depend on each other and need to be deployed in a specific order. Note the connection router and axelarnet gateway each need to know the other's address, so you need to pass `--instantiate2`, and upload both contract before instatiating them. + +Example deployments: + +1. `node deploy-contract.js upload -m [mnemonic] -a [path to artifacts] -c "AxelarnetGateway" --instantiate2 -e devnet` +2. `node deploy-contract.js upload -m [mnemonic] -a [path to artifacts] -c "Router" --instantiate2 -e devnet` +3. `node deploy-contract.js instantiate -m [mnemonic] -c "AxelarnetGateway" --instantiate2 -e devnet` +4. `node deploy-contract.js instantiate -m [mnemonic] -c "Router" --instantiate2 -e devnet` +5. `node deploy-contract.js upload-instantiate -m [mnemonic] -a [path to artifacts] -c "ServiceRegistry" -e devnet` +6. `node deploy-contract.js upload-instantiate -m [mnemonic] -a [path to artifacts] -c "Rewards" -e devnet` +7. `node deploy-contract.js upload-instantiate -m [mnemonic] -a [path to artifacts] -c "Coordinator" -e devnet` +8. `node deploy-contract.js upload-instantiate -m [mnemonic] -a [path to artifacts] -c "Multisig" -e devnet` +9. `node deploy-contract.js upload-instantiate -m [mnemonic] -a [path to artifacts] -c "InterchainTokenService" -e devnet` +10. `node deploy-contract.js upload-instantiate -m [mnemonic] -a [path to artifacts] -c "VotingVerifier" -e devnet -n "avalanche"` +11. `node deploy-contract.js upload-instantiate -m [mnemonic] -a [path to artifacts] -c "Gateway" -e devnet -n "avalanche"` +12. `node deploy-contract.js upload-instantiate -m [mnemonic] -a [path to artifacts] -c "MultisigProver" -e devnet -n "avalanche"` ### Constant Address Deployment diff --git a/cosmwasm/deploy-contract.js b/cosmwasm/deploy-contract.js index e2050ffa..0d4de1a0 100644 --- a/cosmwasm/deploy-contract.js +++ b/cosmwasm/deploy-contract.js @@ -1,7 +1,6 @@ 'use strict'; require('dotenv').config(); -const { isNil } = require('lodash'); const { instantiate2Address } = require('@cosmjs/cosmwasm-stargate'); @@ -14,39 +13,23 @@ const { getSalt, initContractConfig, getAmplifierContractConfig, - updateCodeId, + getCodeId, uploadContract, instantiateContract, } = require('./utils'); -const { Command, Option } = require('commander'); +const { Command } = require('commander'); const { addAmplifierOptions } = require('./cli-utils'); const upload = async (client, wallet, config, options) => { - const { reuseCodeId, contractName, fetchCodeId, instantiate2, salt, chainName } = options; - + const { contractName, instantiate2, salt, chainName } = options; const { contractBaseConfig, contractConfig } = getAmplifierContractConfig(config, options); - if (options.codeId) { - printInfo('Option codeId defined. Skipping upload.'); - return; - } - - if (fetchCodeId) { - printInfo('Option fetchCodeId defined. Skipping upload.'); - return; - } - - if (reuseCodeId && !isNil(contractBaseConfig.lastUploadedCodeId)) { - printInfo('Skipping upload. Reusing previously uploaded bytecode with codeId', contractBaseConfig.lastUploadedCodeId); - return; - } - printInfo('Uploading contract binary'); const { checksum, codeId } = await uploadContract(client, wallet, config, options); - printInfo('Uploaded contract binary'); + printInfo('Uploaded contract binary with codeId', codeId); contractBaseConfig.lastUploadedCodeId = codeId; if (instantiate2) { @@ -60,11 +43,18 @@ const upload = async (client, wallet, config, options) => { }; const instantiate = async (client, wallet, config, options) => { - const { contractName, chainName } = options; + const { contractName, chainName, yes } = options; const { contractConfig } = getAmplifierContractConfig(config, options); - await updateCodeId(client, config, options); + const codeId = await getCodeId(client, config, options); + printInfo('Using code id', codeId); + + if (prompt(`Proceed with instantiation on axelar?`, yes)) { + return; + } + + contractConfig.codeId = codeId; const initMsg = CONTRACTS[contractName].makeInstantiateMsg(config, options, contractConfig); const contractAddress = await instantiateContract(client, wallet, initMsg, config, options); @@ -74,8 +64,13 @@ const instantiate = async (client, wallet, config, options) => { printInfo(`Instantiated ${chainName ? chainName.concat(' ') : ''}${contractName}. Address`, contractAddress); }; -const main = async (options) => { - const { env, uploadOnly, yes } = options; +const uploadInstantiate = async (client, wallet, config, options) => { + await upload(client, wallet, config, options); + await instantiate(client, wallet, config, options); +}; + +const mainProcessor = async (processor, options) => { + const { env } = options; const config = loadConfig(env); initContractConfig(config, options); @@ -83,11 +78,7 @@ const main = async (options) => { const wallet = await prepareWallet(options); const client = await prepareClient(config, wallet); - await upload(client, wallet, config, options); - - if (!(uploadOnly || prompt(`Proceed with deployment on axelar?`, yes))) { - await instantiate(client, wallet, config, options); - } + await processor(client, wallet, config, options); saveConfig(config, env); }; @@ -95,27 +86,45 @@ const main = async (options) => { const programHandler = () => { const program = new Command(); - program.name('upload-contract').description('Upload CosmWasm contracts'); + program.name('deploy-contract').description('Deploy CosmWasm contracts'); - addAmplifierOptions(program, { + const uploadCmd = program + .command('upload') + .description('Upload wasm binary') + .action((options) => { + mainProcessor(upload, options); + }); + addAmplifierOptions(uploadCmd, { contractOptions: true, storeOptions: true, + instantiate2Options: true, + }); + + const instantiateCmd = program + .command('instantiate') + .description('Instantiate contract') + .action((options) => { + mainProcessor(instantiate, options); + }); + addAmplifierOptions(instantiateCmd, { + contractOptions: true, instantiateOptions: true, instantiate2Options: true, codeId: true, fetchCodeId: true, }); - program.addOption(new Option('-r, --reuseCodeId', 'reuse code Id')); - program.addOption( - new Option( - '-u, --uploadOnly', - 'upload the contract without instantiating. prints expected contract address if --instantiate2 is passed', - ), - ); - - program.action((options) => { - main(options); + const uploadInstantiateCmd = program + .command('upload-instantiate') + .description('Upload wasm binary and instantiate contract') + .action((options) => { + mainProcessor(uploadInstantiate, options); + }); + addAmplifierOptions(uploadInstantiateCmd, { + contractOptions: true, + storeOptions: true, + instantiateOptions: true, + instantiate2Options: true, }); program.parse(); diff --git a/cosmwasm/submit-proposal.js b/cosmwasm/submit-proposal.js index 23db85c7..d959a822 100644 --- a/cosmwasm/submit-proposal.js +++ b/cosmwasm/submit-proposal.js @@ -16,7 +16,7 @@ const { initContractConfig, getAmplifierBaseContractConfig, getAmplifierContractConfig, - updateCodeId, + getCodeId, addDefaultInstantiateAddresses, getChainTruncationParams, decodeProposalAttributes, @@ -121,7 +121,7 @@ const instantiate = async (client, wallet, config, options) => { const { contractName, instantiate2, predictOnly } = options; const { contractConfig } = getAmplifierContractConfig(config, options); - await updateCodeId(client, config, options); + contractConfig.codeId = await getCodeId(client, config, options); let contractAddress; @@ -206,7 +206,8 @@ const paramChange = async (client, wallet, config, options) => { }; const migrate = async (client, wallet, config, options) => { - await updateCodeId(client, config, options); + const { contractConfig } = getAmplifierContractConfig(config, options); + contractConfig.codeId = await getCodeId(client, config, options); const proposal = encodeMigrateContractProposal(config, options); diff --git a/cosmwasm/utils.js b/cosmwasm/utils.js index b2e8ca41..353c1b98 100644 --- a/cosmwasm/utils.js +++ b/cosmwasm/utils.js @@ -106,22 +106,24 @@ const getAmplifierContractConfig = (config, { contractName, chainName }) => { return { contractBaseConfig, contractConfig }; }; -const updateCodeId = async (client, config, options) => { - const { fetchCodeId, codeId } = options; +const getCodeId = async (client, config, options) => { + const { fetchCodeId, codeId, contractName } = options; - const { contractBaseConfig, contractConfig } = getAmplifierContractConfig(config, options); + const contractBaseConfig = getAmplifierBaseContractConfig(config, contractName); if (codeId) { - contractConfig.codeId = codeId; - } else if (fetchCodeId) { - contractConfig.codeId = await fetchCodeIdFromCodeHash(client, contractBaseConfig); - } else if (contractBaseConfig.lastUploadedCodeId) { - contractConfig.codeId = contractBaseConfig.lastUploadedCodeId; - } else { - throw new Error('Code Id is not defined'); + return codeId; + } + + if (fetchCodeId) { + return fetchCodeIdFromCodeHash(client, contractBaseConfig); + } + + if (contractBaseConfig.lastUploadedCodeId) { + return contractBaseConfig.lastUploadedCodeId; } - printInfo('Using code id', contractConfig.codeId); + throw new Error('Code Id is not defined'); }; const uploadContract = async (client, wallet, config, options) => { @@ -870,7 +872,7 @@ module.exports = { initContractConfig, getAmplifierBaseContractConfig, getAmplifierContractConfig, - updateCodeId, + getCodeId, uploadContract, instantiateContract, fetchCodeIdFromCodeHash,