Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(amplifier): support for execute message through governance #312

Merged
merged 1 commit into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions cosmwasm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,3 +187,14 @@ Order of execution to satisfy dependencies:
9. `node cosmwasm/submit-proposal.js --proposalType instantiate -c VotingVerifier -t "VotingVerifier roposal title" -d "VotingVerifier proposal description" -r $RUN_AS_ACCOUNT --deposit 100000000 --instantiate2 --fetchCodeId -y -n "avalanche"`
10. `node cosmwasm/submit-proposal.js --proposalType instantiate -c Gateway -t "Gateway roposal title" -d "Gateway proposal description" -r $RUN_AS_ACCOUNT --deposit 100000000 --instantiate2 --fetchCodeId -y -n "avalanche"`
11. `node cosmwasm/submit-proposal.js --proposalType instantiate -c MultisigProver -t "MultisigProver roposal title" -d "MultisigProver proposal description" -r $RUN_AS_ACCOUNT --deposit 100000000 --instantiate2 --fetchCodeId -y -n "avalanche"`


### Execute a contract through governance proposal

To submit a governance proposal to execute a contract, use the `submit-proposal` script with the `--proposalType execute` option. The `--msg` option should be used to pass the execute message.

Example usage:

```
node cosmwasm/submit-proposal.js --proposalType execute -c Router -t "Proposal title" -d "Proposal description" --deposit 100000000 --msg '{"register_chain":{"chain":"avalanche","gateway_address":"axelar17cnq5hujmkf2lr2c5hatqmhzlvwm365rqc5ugryphxeftavjef9q89zxvp","msg_id_format":"hex_tx_hash_and_event_index"}}'
```
50 changes: 47 additions & 3 deletions cosmwasm/submit-proposal.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,19 @@ const {
encodeStoreCodeProposal,
encodeInstantiateProposal,
encodeInstantiate2Proposal,
encodeExecuteContractProposal,
submitProposal,
makeInstantiateMsg,
instantiate2AddressForProposal,
governanceAddress,
} = require('./utils');
const { saveConfig, loadConfig, printInfo, prompt } = require('../evm/utils');
const { StoreCodeProposal, InstantiateContractProposal, InstantiateContract2Proposal } = require('cosmjs-types/cosmwasm/wasm/v1/proposal');
const {
StoreCodeProposal,
InstantiateContractProposal,
InstantiateContract2Proposal,
ExecuteContractProposal,
} = require('cosmjs-types/cosmwasm/wasm/v1/proposal');

const { Command, Option } = require('commander');

Expand Down Expand Up @@ -136,6 +142,30 @@ const instantiate = async (client, wallet, config, options, chainName) => {
});
};

const execute = (client, wallet, config, options, chainName) => {
const { contractName } = options;
const {
axelar: {
contracts: { [contractName]: contractConfig },
},
chains: { [chainName]: chainConfig },
} = config;

const proposal = encodeExecuteContractProposal(config, options, chainName);

printProposal(proposal, ExecuteContractProposal);

if (prompt(`Proceed with proposal submission?`, options.yes)) {
return Promise.resolve();
}

return submitProposal(client, wallet, config, options, proposal).then((proposalId) => {
printInfo('Proposal submitted', proposalId);

updateContractConfig(contractConfig, chainConfig, 'executeProposalId', proposalId);
});
};

const main = async (options) => {
const { env, proposalType, contractName } = options;
const config = loadConfig(env);
Expand Down Expand Up @@ -166,6 +196,14 @@ const main = async (options) => {
}, Promise.resolve());
}

case 'execute': {
const chains = getChains(config, options);

return chains.reduce((promise, chain) => {
return promise.then(() => execute(client, wallet, config, options, chain.toLowerCase()));
}, Promise.resolve());
}

default:
throw new Error('Invalid proposal type');
}
Expand Down Expand Up @@ -203,9 +241,13 @@ const programHandler = () => {
program.addOption(new Option('-t, --title <title>', 'title of proposal').makeOptionMandatory(true));
program.addOption(new Option('-d, --description <description>', 'description of proposal').makeOptionMandatory(true));
program.addOption(new Option('--deposit <deposit>', 'the proposal deposit').makeOptionMandatory(true));
program.addOption(new Option('-r, --runAs <runAs>', 'the address that will execute the message').makeOptionMandatory(true));
program.addOption(
new Option('--proposalType <proposalType>', 'proposal type').choices(['store', 'instantiate']).makeOptionMandatory(true),
new Option('-r, --runAs <runAs>', 'the address that will execute the message. Defaults to governance address').default(
governanceAddress,
),
);
program.addOption(
new Option('--proposalType <proposalType>', 'proposal type').choices(['store', 'instantiate', 'execute']).makeOptionMandatory(true),
);
program.addOption(new Option('--predictOnly', 'output the predicted changes only').env('PREDICT_ONLY'));

Expand All @@ -219,6 +261,8 @@ const programHandler = () => {

program.addOption(new Option('--fetchCodeId', 'fetch code id from the chain by comparing to the uploaded code hash'));

program.addOption(new Option('--msg <msg>', 'json encoded message to submit with an execute contract proposal'));

program.action((options) => {
main(options);
});
Expand Down
33 changes: 32 additions & 1 deletion cosmwasm/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ const { calculateFee, GasPrice } = require('@cosmjs/stargate');
const { instantiate2Address, SigningCosmWasmClient } = require('@cosmjs/cosmwasm-stargate');
const { DirectSecp256k1HdWallet } = require('@cosmjs/proto-signing');
const { MsgSubmitProposal } = require('cosmjs-types/cosmos/gov/v1beta1/tx');
const { StoreCodeProposal, InstantiateContractProposal, InstantiateContract2Proposal } = require('cosmjs-types/cosmwasm/wasm/v1/proposal');
const {
StoreCodeProposal,
InstantiateContractProposal,
InstantiateContract2Proposal,
ExecuteContractProposal,
} = require('cosmjs-types/cosmwasm/wasm/v1/proposal');
const { AccessType } = require('cosmjs-types/cosmwasm/wasm/v1/types');
const { getSaltFromKey, isString, isStringArray, isKeccak256Hash, isNumber, toBigNumberString } = require('../evm/utils');
const { normalizeBech32 } = require('@cosmjs/encoding');
Expand Down Expand Up @@ -558,6 +563,22 @@ const getInstantiateContract2Params = (config, options, msg) => {
};
};

const getExecuteContractParams = (config, options, chainName) => {
const { contractName, msg } = options;
const {
axelar: {
contracts: { [contractName]: contractConfig },
},
chains: { [chainName]: chainConfig },
} = config;

return {
...getSubmitProposalParams(options),
contract: chainConfig ? contractConfig[chainConfig.axelarId].address : contractConfig.address,
msg: Buffer.from(msg),
};
};

const encodeStoreCodeProposal = (options) => {
const proposal = StoreCodeProposal.fromPartial(getStoreCodeParams(options));

Expand Down Expand Up @@ -593,6 +614,15 @@ const encodeInstantiate2Proposal = (config, options, msg) => {
};
};

const encodeExecuteContractProposal = (config, options, chainName) => {
const proposal = ExecuteContractProposal.fromPartial(getExecuteContractParams(config, options, chainName));

return {
typeUrl: '/cosmwasm.wasm.v1.ExecuteContractProposal',
value: Uint8Array.from(ExecuteContractProposal.encode(proposal).finish()),
};
};

const encodeSubmitProposal = (content, config, options, proposer) => {
const {
axelar: { tokenSymbol },
Expand Down Expand Up @@ -642,6 +672,7 @@ module.exports = {
encodeStoreCodeProposal,
encodeInstantiateProposal,
encodeInstantiate2Proposal,
encodeExecuteContractProposal,
submitProposal,
isValidCosmosAddress,
};
Loading