diff --git a/packages/cosmwasm/src/signingcosmwasmclient.spec.ts b/packages/cosmwasm/src/signingcosmwasmclient.spec.ts index 1a0e07099d..e7d5629050 100644 --- a/packages/cosmwasm/src/signingcosmwasmclient.spec.ts +++ b/packages/cosmwasm/src/signingcosmwasmclient.spec.ts @@ -673,6 +673,8 @@ import { expect(result.height).toBeGreaterThan(0); expect(result.gasWanted).toBeGreaterThan(0); expect(result.gasUsed).toBeGreaterThan(0); + // One MsgExecuteContractResponse (and thus one `data` entry) per instruction. + expect(result.data.length).toEqual(1); const wasmEvent = result.events.find((e) => e.type === "wasm"); assert(wasmEvent, "Event of type wasm expected"); expect(wasmEvent.attributes).toContain({ key: "action", value: "release" }); @@ -794,6 +796,8 @@ import { const { events } = result; const wasmEvents = events.filter((e) => e.type == "wasm"); expect(wasmEvents.length).toEqual(2); + // One `data` entry per instruction, in order. + expect(result.data.length).toEqual(2); const [wasmEvent1, wasmEvent2] = wasmEvents; expect(wasmEvent1.type).toEqual("wasm"); expect(wasmEvent1.attributes).toContain({ key: "action", value: "release" }); diff --git a/packages/cosmwasm/src/signingcosmwasmclient.ts b/packages/cosmwasm/src/signingcosmwasmclient.ts index 4d8ec7d791..5008c4d152 100644 --- a/packages/cosmwasm/src/signingcosmwasmclient.ts +++ b/packages/cosmwasm/src/signingcosmwasmclient.ts @@ -44,6 +44,7 @@ import { TxRaw } from "cosmjs-types/cosmos/tx/v1beta1/tx"; import { MsgClearAdmin, MsgExecuteContract, + MsgExecuteContractResponse, MsgInstantiateContract, MsgInstantiateContract2, MsgMigrateContract, @@ -163,6 +164,12 @@ export interface ExecuteResult { /** Transaction hash (might be used as transaction ID). Guaranteed to be non-empty upper-case hex */ readonly transactionHash: string; readonly events: readonly Event[]; + /** + * The `data` bytes each executed contract returned via `Response::set_data`, + * one entry per instruction in the same order. Empty for chains running + * Cosmos SDK < 0.46, which do not expose message responses. + */ + readonly data: readonly Uint8Array[]; readonly gasWanted: bigint; readonly gasUsed: bigint; } @@ -540,6 +547,11 @@ export class SigningCosmWasmClient extends CosmWasmClient { height: result.height, transactionHash: result.transactionHash, events: result.events, + // Each MsgExecuteContract produces a MsgExecuteContractResponse whose + // `data` field carries what the contract set via `Response::set_data`. + data: result.msgResponses.map( + (msgResponse) => MsgExecuteContractResponse.decode(msgResponse.value).data, + ), gasWanted: result.gasWanted, gasUsed: result.gasUsed, }; diff --git a/packages/proto-signing/src/pubkey.spec.ts b/packages/proto-signing/src/pubkey.spec.ts index 8a4cab11ce..458b30ad81 100644 --- a/packages/proto-signing/src/pubkey.spec.ts +++ b/packages/proto-signing/src/pubkey.spec.ts @@ -64,6 +64,25 @@ describe("pubkey", () => { }); }); + it("works for multisig threshold pubkeys", () => { + // Build a 2-of-2 multisig over the secp256k1 and ed25519 keys above, + // encode it to protobuf, then check decodePubkey reconstructs it. This + // covers the LegacyAminoPubKey branch on both encode and decode. + const multisigPubkey = { + type: "tendermint/PubKeyMultisigThreshold", + value: { + threshold: "2", + pubkeys: [ + { type: "tendermint/PubKeySecp256k1", value: defaultPubkeyBase64 }, + { type: "tendermint/PubKeyEd25519", value: ed25519PubkeyBase64 }, + ], + }, + }; + const encoded = encodePubkey(multisigPubkey); + expect(encoded.typeUrl).toEqual("/cosmos.crypto.multisig.LegacyAminoPubKey"); + expect(decodePubkey(encoded)).toEqual(multisigPubkey); + }); + it("throws for unsupported pubkey types", () => { const pubkey = { typeUrl: "/cosmos.crypto.unknown.PubKey",