From 946e2ceecff832721a22c42afe19eab459042ac7 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Wed, 28 Feb 2024 19:01:11 +0100 Subject: [PATCH] Restore logs.findAttribute. Add event based findAttribute --- .../src/cosmwasmclient.spec.ts | 6 ++--- .../src/modules/wasm/queries.spec.ts | 13 +++++----- .../src/signingcosmwasmclient.ts | 25 ++++++++++++++++--- packages/stargate/src/logs.ts | 5 ++-- 4 files changed, 34 insertions(+), 15 deletions(-) diff --git a/packages/cosmwasm-stargate/src/cosmwasmclient.spec.ts b/packages/cosmwasm-stargate/src/cosmwasmclient.spec.ts index 10be293c..1ea19380 100644 --- a/packages/cosmwasm-stargate/src/cosmwasmclient.spec.ts +++ b/packages/cosmwasm-stargate/src/cosmwasmclient.spec.ts @@ -10,13 +10,13 @@ import { Registry, TxBodyEncodeObject, } from "@cosmjs/proto-signing"; -import { assertIsDeliverTxSuccess, coins, logs, MsgSendEncodeObject, StdFee } from "@cosmjs/stargate"; +import { assertIsDeliverTxSuccess, coins, MsgSendEncodeObject, StdFee } from "@cosmjs/stargate"; import { assert, sleep } from "@cosmjs/utils"; import { TxRaw } from "cosmjs-types/cosmos/tx/v1beta1/tx"; import { ReadonlyDate } from "readonly-date"; import { Code, CosmWasmClient, PrivateCosmWasmClient } from "./cosmwasmclient"; -import { SigningCosmWasmClient } from "./signingcosmwasmclient"; +import { findAttribute, SigningCosmWasmClient } from "./signingcosmwasmclient"; import { alice, defaultInstantiateFee, @@ -222,7 +222,7 @@ describe("CosmWasmClient", () => { const signedTx = Uint8Array.from(TxRaw.encode(txRaw).finish()); const result = await client.broadcastTx(signedTx); assertIsDeliverTxSuccess(result); - const amountAttr = logs.findAttribute(result.events, "transfer", "amount"); + const amountAttr = findAttribute(result.events, "transfer", "amount"); expect(amountAttr.value).toEqual("1234567ucosm"); expect(result.transactionHash).toMatch(/^[0-9A-F]{64}$/); }); diff --git a/packages/cosmwasm-stargate/src/modules/wasm/queries.spec.ts b/packages/cosmwasm-stargate/src/modules/wasm/queries.spec.ts index 8ef7d111..81a34cb1 100644 --- a/packages/cosmwasm-stargate/src/modules/wasm/queries.spec.ts +++ b/packages/cosmwasm-stargate/src/modules/wasm/queries.spec.ts @@ -7,7 +7,6 @@ import { coin, coins, DeliverTxResponse, - logs, SigningStargateClient, StdFee, } from "@cosmjs/stargate"; @@ -15,7 +14,7 @@ import { assert, assertDefined } from "@cosmjs/utils"; import { MsgExecuteContract, MsgInstantiateContract, MsgStoreCode } from "cosmjs-types/cosmwasm/wasm/v1/tx"; import { AbsoluteTxPosition, ContractCodeHistoryOperationType } from "cosmjs-types/cosmwasm/wasm/v1/types"; -import { SigningCosmWasmClient } from "../../signingcosmwasmclient"; +import { findAttribute, SigningCosmWasmClient } from "../../signingcosmwasmclient"; import { alice, bech32AddressMatcher, @@ -385,11 +384,11 @@ describe("WasmExtension", () => { { const result = await uploadContract(wallet, getHackatom()); assertIsDeliverTxSuccess(result); - const codeIdAttr = logs.findAttribute(result.events, "store_code", "code_id"); + const codeIdAttr = findAttribute(result.events, "store_code", "code_id"); codeId = Number.parseInt(codeIdAttr.value, 10); expect(codeId).toBeGreaterThanOrEqual(1); expect(codeId).toBeLessThanOrEqual(200); - const actionAttr = logs.findAttribute(result.events, "message", "module"); + const actionAttr = findAttribute(result.events, "message", "module"); expect(actionAttr.value).toEqual("wasm"); } @@ -399,11 +398,11 @@ describe("WasmExtension", () => { { const result = await instantiateContract(wallet, codeId, beneficiaryAddress, funds); assertIsDeliverTxSuccess(result); - const contractAddressAttr = logs.findAttribute(result.events, "instantiate", "_contract_address"); + const contractAddressAttr = findAttribute(result.events, "instantiate", "_contract_address"); contractAddress = contractAddressAttr.value; - const amountAttr = logs.findAttribute(result.events, "transfer", "amount"); + const amountAttr = findAttribute(result.events, "transfer", "amount"); expect(amountAttr.value).toEqual("1234ucosm,321ustake"); - const actionAttr = logs.findAttribute(result.events, "message", "module"); + const actionAttr = findAttribute(result.events, "message", "module"); expect(actionAttr.value).toEqual("wasm"); const balanceUcosm = await client.bank.balance(contractAddress, "ucosm"); diff --git a/packages/cosmwasm-stargate/src/signingcosmwasmclient.ts b/packages/cosmwasm-stargate/src/signingcosmwasmclient.ts index 411b8965..40b7faf6 100644 --- a/packages/cosmwasm-stargate/src/signingcosmwasmclient.ts +++ b/packages/cosmwasm-stargate/src/signingcosmwasmclient.ts @@ -15,6 +15,7 @@ import { } from "@cosmjs/proto-signing"; import { AminoTypes, + Attribute, calculateFee, Coin, createDefaultAminoConverters, @@ -158,6 +159,24 @@ export interface ExecuteResult { readonly gasUsed: bigint; } +/** + * Searches in events for the first event of the given event type and in that event + * for the first first attribute with the given attribute key. + * + * Throws if the attribute was not found. + */ +export function findAttribute(events: readonly Event[], eventType: string, attrKey: string): Attribute { + const out = events + .find((event) => event.type === eventType) + ?.attributes.find((attr) => attr.key === attrKey); + if (!out) { + throw new Error( + `Could not find attribute '${attrKey}' in first event of type '${eventType}' in first log.`, + ); + } + return out; +} + function createDeliverTxResponseErrorMessage(result: DeliverTxResponse): string { return `Error when broadcasting tx ${result.transactionHash} at height ${result.height}. Code: ${result.code}; Raw log: ${result.rawLog}`; } @@ -288,7 +307,7 @@ export class SigningCosmWasmClient extends CosmWasmClient { if (isDeliverTxFailure(result)) { throw new Error(createDeliverTxResponseErrorMessage(result)); } - const codeIdAttr = logs.findAttribute(result.events, "store_code", "code_id"); + const codeIdAttr = findAttribute(result.events, "store_code", "code_id"); return { checksum: toHex(sha256(wasmCode)), originalSize: wasmCode.length, @@ -326,7 +345,7 @@ export class SigningCosmWasmClient extends CosmWasmClient { if (isDeliverTxFailure(result)) { throw new Error(createDeliverTxResponseErrorMessage(result)); } - const contractAddressAttr = logs.findAttribute(result.events, "instantiate", "_contract_address"); + const contractAddressAttr = findAttribute(result.events, "instantiate", "_contract_address"); return { contractAddress: contractAddressAttr.value, logs: [], @@ -364,7 +383,7 @@ export class SigningCosmWasmClient extends CosmWasmClient { if (isDeliverTxFailure(result)) { throw new Error(createDeliverTxResponseErrorMessage(result)); } - const contractAddressAttr = logs.findAttribute(result.events, "instantiate", "_contract_address"); + const contractAddressAttr = findAttribute(result.events, "instantiate", "_contract_address"); return { contractAddress: contractAddressAttr.value, logs: [], diff --git a/packages/stargate/src/logs.ts b/packages/stargate/src/logs.ts index 93003664..f899c8fe 100644 --- a/packages/stargate/src/logs.ts +++ b/packages/stargate/src/logs.ts @@ -69,8 +69,9 @@ export function parseRawLog(input = "[]"): readonly Log[] { * * Throws if the attribute was not found. */ -export function findAttribute(events: readonly Event[], eventType: string, attrKey: string): Attribute { - const out = events +export function findAttribute(logs: readonly Log[], eventType: string, attrKey: string): Attribute { + const firstLogs = logs.find(() => true); + const out = firstLogs?.events .find((event) => event.type === eventType) ?.attributes.find((attr) => attr.key === attrKey); if (!out) {