diff --git a/CHANGELOG.md b/CHANGELOG.md index 003d5d5ce2..7aa01a8771 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to - @cosmjs/encoding: Add `lossy` parameter to `fromUtf8` allowing the use of a replacement charater instead of throwing. +- @cosmjs/stargate: Add structured `Events`s to `IndexTx.events`. ## [0.29.2] - 2022-10-13 diff --git a/packages/cosmwasm-stargate/src/cosmwasmclient.ts b/packages/cosmwasm-stargate/src/cosmwasmclient.ts index 1c5162c2c4..1a6ba2e90c 100644 --- a/packages/cosmwasm-stargate/src/cosmwasmclient.ts +++ b/packages/cosmwasm-stargate/src/cosmwasmclient.ts @@ -10,6 +10,7 @@ import { BroadcastTxError, Coin, DeliverTxResponse, + fromTendermint34Event, IndexedTx, isSearchByHeightQuery, isSearchBySentFromOrToQuery, @@ -462,6 +463,7 @@ export class CosmWasmClient { height: tx.height, hash: toHex(tx.hash).toUpperCase(), code: tx.result.code, + events: tx.result.events.map(fromTendermint34Event), rawLog: tx.result.log || "", tx: tx.tx, gasUsed: tx.result.gasUsed, diff --git a/packages/stargate/src/events.ts b/packages/stargate/src/events.ts new file mode 100644 index 0000000000..b4b70cce29 --- /dev/null +++ b/packages/stargate/src/events.ts @@ -0,0 +1,46 @@ +import { fromUtf8 } from "@cosmjs/encoding"; +import { tendermint34 } from "@cosmjs/tendermint-rpc"; + +/** + * An event attribute. + * + * This is the same attribute type as tendermint34.Attribute and tendermint35.EventAttribute + * but `key` and `value` are unified to strings. The conversion + * from bytes to string in the Tendermint 0.34 case should be done by performing + * [lossy] UTF-8 decoding. + * + * [lossy]: https://doc.rust-lang.org/stable/std/string/struct.String.html#method.from_utf8_lossy + */ +export interface Attribute { + readonly key: string; + readonly value: string; +} + +/** + * The same event type as tendermint34.Event and tendermint35.Event + * but attribute keys and values are unified to strings. The conversion + * from bytes to string in the Tendermint 0.34 case should be done by performing + * [lossy] UTF-8 decoding. + * + * [lossy]: https://doc.rust-lang.org/stable/std/string/struct.String.html#method.from_utf8_lossy + */ +export interface Event { + readonly type: string; + readonly attributes: readonly Attribute[]; +} + +/** + * Takes a Tendemrint 0.34 event with binary encoded key and value + * and converts it into an `Event` with string attributes. + */ +export function fromTendermint34Event(event: tendermint34.Event): Event { + return { + type: event.type, + attributes: event.attributes.map( + (attr): Attribute => ({ + key: fromUtf8(attr.key, true), + value: fromUtf8(attr.value, true), + }), + ), + }; +} diff --git a/packages/stargate/src/index.ts b/packages/stargate/src/index.ts index 5b2145068f..87eac5ab87 100644 --- a/packages/stargate/src/index.ts +++ b/packages/stargate/src/index.ts @@ -1,5 +1,6 @@ export { Account, accountFromAny, AccountParser } from "./accounts"; export { AminoConverter, AminoConverters, AminoTypes } from "./aminotypes"; +export { Attribute, Event, fromTendermint34Event } from "./events"; export { calculateFee, GasPrice } from "./fee"; export * as logs from "./logs"; export { diff --git a/packages/stargate/src/logs.ts b/packages/stargate/src/logs.ts index 91be9109ac..f899c8fe0d 100644 --- a/packages/stargate/src/logs.ts +++ b/packages/stargate/src/logs.ts @@ -1,15 +1,7 @@ /* eslint-disable @typescript-eslint/naming-convention */ import { isNonNullObject } from "@cosmjs/utils"; -export interface Attribute { - readonly key: string; - readonly value: string; -} - -export interface Event { - readonly type: string; - readonly attributes: readonly Attribute[]; -} +import { Attribute, Event } from "./events"; export interface Log { readonly msg_index: number; diff --git a/packages/stargate/src/stargateclient.ts b/packages/stargate/src/stargateclient.ts index a4b05c0b9b..d0abf3845d 100644 --- a/packages/stargate/src/stargateclient.ts +++ b/packages/stargate/src/stargateclient.ts @@ -10,6 +10,7 @@ import { QueryDelegatorDelegationsResponse } from "cosmjs-types/cosmos/staking/v import { DelegationResponse } from "cosmjs-types/cosmos/staking/v1beta1/staking"; import { Account, accountFromAny, AccountParser } from "./accounts"; +import { Event, fromTendermint34Event } from "./events"; import { AuthExtension, BankExtension, @@ -64,6 +65,14 @@ export interface IndexedTx { readonly hash: string; /** Transaction execution error code. 0 on success. */ readonly code: number; + readonly events: readonly Event[]; + /** + * A string-based log document. + * + * This currently seems to merge attributes of multiple events into one event per type + * (https://github.com/tendermint/tendermint/issues/9595). You might want to use the `events` + * field instead. + */ readonly rawLog: string; /** * Raw transaction bytes stored in Tendermint. @@ -453,6 +462,7 @@ export class StargateClient { height: tx.height, hash: toHex(tx.hash).toUpperCase(), code: tx.result.code, + events: tx.result.events.map(fromTendermint34Event), rawLog: tx.result.log || "", tx: tx.tx, gasUsed: tx.result.gasUsed,