Merge pull request #1192 from cosmos/executeMultiple

Add SigningCosmWasmClient.executeMultiple
This commit is contained in:
Simon Warta 2022-06-27 16:13:30 +02:00 committed by GitHub
commit 92ee134a12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 96 additions and 6 deletions

View File

@ -12,7 +12,10 @@ and this project adheres to
`makeMultisignedTx` but returns bytes ready to broadcast ([#1176]).
- @cosmjs/tendermint-rpc: Add fields `codespace` and `info` to
`AbciQueryResponse`.
- @cosmjs/cosmwasm-stargate: Add `SigningCosmWasmClient.executeMultiple`
([#1072]).
[#1072]: https://github.com/cosmos/cosmjs/issues/1072
[#1176]: https://github.com/cosmos/cosmjs/pull/1176
### Fixed

View File

@ -21,6 +21,7 @@ export {
} from "./modules";
export {
ChangeAdminResult,
ExecuteInstruction,
ExecuteResult,
InstantiateOptions,
InstantiateResult,

View File

@ -530,6 +530,68 @@ describe("SigningCosmWasmClient", () => {
});
});
describe("executeMultiple", () => {
it("works", async () => {
pendingWithoutWasmd();
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(alice.mnemonic, { prefix: wasmd.prefix });
const options = { ...defaultSigningClientOptions, prefix: wasmd.prefix };
const client = await SigningCosmWasmClient.connectWithSigner(wasmd.endpoint, wallet, options);
const { codeId } = await client.upload(alice.address0, getHackatom().data, defaultUploadFee);
// instantiate
const funds = [coin(233444, "ucosm"), coin(5454, "ustake")];
const beneficiaryAddress1 = makeRandomAddress();
const beneficiaryAddress2 = makeRandomAddress();
const { contractAddress: contractAddress1 } = await client.instantiate(
alice.address0,
codeId,
{
verifier: alice.address0,
beneficiary: beneficiaryAddress1,
},
"amazing random contract",
defaultInstantiateFee,
{ funds: funds },
);
const { contractAddress: contractAddress2 } = await client.instantiate(
alice.address0,
codeId,
{
verifier: alice.address0,
beneficiary: beneficiaryAddress2,
},
"amazing random contract",
defaultInstantiateFee,
{ funds: funds },
);
// execute
const result = await client.executeMultiple(
alice.address0,
[
{ contractAddress: contractAddress1, msg: { release: {} } },
{ contractAddress: contractAddress2, msg: { release: {} } },
],
"auto",
);
expect(result.logs.length).toEqual(2);
const wasmEvent1 = result.logs[0].events.find((e) => e.type === "wasm");
assert(wasmEvent1, "Event of type wasm expected");
expect(wasmEvent1.attributes).toContain({ key: "action", value: "release" });
expect(wasmEvent1.attributes).toContain({
key: "destination",
value: beneficiaryAddress1,
});
const wasmEvent2 = result.logs[1].events.find((e) => e.type === "wasm");
assert(wasmEvent2, "Event of type wasm expected");
expect(wasmEvent2.attributes).toContain({ key: "action", value: "release" });
expect(wasmEvent2.attributes).toContain({
key: "destination",
value: beneficiaryAddress2,
});
client.disconnect();
});
});
describe("sendTokens", () => {
it("works with direct signer", async () => {
pendingWithoutWasmd();

View File

@ -135,6 +135,12 @@ export interface MigrateResult {
readonly gasUsed: number;
}
export interface ExecuteInstruction {
contractAddress: string;
msg: Record<string, unknown>;
funds?: readonly Coin[];
}
export interface ExecuteResult {
readonly logs: readonly logs.Log[];
/** Block height in which the transaction is included */
@ -396,16 +402,33 @@ export class SigningCosmWasmClient extends CosmWasmClient {
memo = "",
funds?: readonly Coin[],
): Promise<ExecuteResult> {
const executeContractMsg: MsgExecuteContractEncodeObject = {
const instruction: ExecuteInstruction = {
contractAddress: contractAddress,
msg: msg,
funds: funds,
};
return this.executeMultiple(senderAddress, [instruction], fee, memo);
}
/**
* Like `execute` but allows executing multiple messages in one transaction.
*/
public async executeMultiple(
senderAddress: string,
instructions: readonly ExecuteInstruction[],
fee: StdFee | "auto" | number,
memo = "",
): Promise<ExecuteResult> {
const msgs: MsgExecuteContractEncodeObject[] = instructions.map((i) => ({
typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
value: MsgExecuteContract.fromPartial({
sender: senderAddress,
contract: contractAddress,
msg: toUtf8(JSON.stringify(msg)),
funds: [...(funds || [])],
contract: i.contractAddress,
msg: toUtf8(JSON.stringify(i.msg)),
funds: [...(i.funds || [])],
}),
};
const result = await this.signAndBroadcast(senderAddress, [executeContractMsg], fee, memo);
}));
const result = await this.signAndBroadcast(senderAddress, msgs, fee, memo);
if (isDeliverTxFailure(result)) {
throw new Error(createDeliverTxResponseErrorMessage(result));
}

View File

@ -55,6 +55,7 @@ export const wasmd = {
export const defaultSigningClientOptions: SigningCosmWasmClientOptions = {
broadcastPollIntervalMs: 300,
broadcastTimeoutMs: 8_000,
gasPrice: defaultGasPrice,
};
export function getHackatom(): ContractUploadInstructions {