Skip to content
LogoLogo

Events

Event subscription APIs

Fetch events posted by the consensus node.

GET/events

Fetch a batch of events posted by the consensus node and matching a specified query string.

The query grammar is defined in pubsub/query/syntax. An empty query matches all events; otherwise a query comprises one or more terms comparing event metadata to target values. For example, to select new block events:

tm.event = 'NewBlock'

Multiple terms can be combined with AND, for example to match the transaction event with a given hash, use:

tm.event = 'Tx' AND tx.hash = 'EA7B33F'

The comparison operators include =, <, <=, >, >=, and CONTAINS. Operands may be strings (in single quotes), numbers, dates, or timestamps. In addition, the EXISTS operator allows you to check for the presence of an attribute regardless of its value.

Tendermint defines a tm.event attribute for all events. Transactions are also assigned tx.hash and tx.height attributes. Other attributes are provided by the application as ABCI Event records. The name of the event in the query is formed by combining the type and attribute key with a period. For example, given:

[]abci.Event{{
    Type: "reward",
    Attributes: []abci.EventAttribute{
        {Key: "address", Value: "cosmos1xyz012pdq"},
        {Key: "amount", Value: "45.62"},
        {Key: "balance", Value: "100.390001"},
    },
}}

the query may refer to the names"reward.address,"reward.amount, and reward.balance, as in:

reward.address EXISTS AND reward.balance > 45

The node maintains a log of all events within an operator-defined time window. The /events method returns the most recent items from the log that match the query. Each item returned includes a cursor that marks its location in the log. Cursors can be passed via the before and after parameters to fetch events earlier in the log.

Query Parameters

filter
object

maxItems
integer
Example10
after
string
Example0005d7c09065e9a7-01cf
before
string
Example0005d7c09065e9a7-01cf
waitTime
integer
Example5000000000

Responses

Subscribe for events via WebSocket.

GET/subscribe

To tell which events you want, you need to provide a query. query is a string, which has a form: "condition AND condition ..." (no OR at the moment). condition has a form: "key operation operand". key is a string with a restricted set of possible symbols ( \t\n\r\()"'=>< are not allowed). operation can be "=", "<", "<=", ">", ">=", "CONTAINS" AND "EXISTS". operand can be a string (escaped with single quotes), number, date or time.

Examples: tm.event = 'NewBlock' # new blocks tm.event = 'CompleteProposal' # node got a complete proposal tm.event = 'Tx' AND tx.hash = 'XYZ' # single transaction tm.event = 'Tx' AND tx.height = 5 # all txs of the fifth block tx.height = 5 # all txs of the fifth block

Tendermint provides a few predefined keys: tm.event, tx.hash and tx.height. Note for transactions, you can define additional keys by providing events with DeliverTx response.

import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/libs/pubsub/query" )

abci.ResponseDeliverTx{ Events: []abci.Event{ { Type: "rewards.withdraw", Attributes: []abci.EventAttribute{ {Key: "address", Value: "AddrA", Index: true}, {Key: "source", Value: "SrcX", Index: true}, {Key: "amount", Value: "...", Index: true}, {Key: "balance", Value: "...", Index: true}, }, }, { Type: "rewards.withdraw", Attributes: []abci.EventAttribute{ {Key: "address", Value: "AddrB", Index: true}, {Key: "source", Value: "SrcY", Index: true}, {Key: "amount", Value: "...", Index: true}, {Key: "balance", Value: "...", Index: true}, }, }, { Type: "transfer", Attributes: []abci.EventAttribute{ {Key: "sender", Value: "AddrC", Index: true}, {Key: "recipient", Value: "AddrD", Index: true}, {Key: "amount", Value: "...", Index: true}, }, }, }, }

All events are indexed by a composite key of the form {eventType}.{evenAttrKey}. In the above examples, the following keys would be indexed:

  • rewards.withdraw.address
  • rewards.withdraw.source
  • rewards.withdraw.amount
  • rewards.withdraw.balance
  • transfer.sender
  • transfer.recipient
  • transfer.amount

Multiple event types with duplicate keys are allowed and are meant to categorize unique and distinct events. In the above example, all events indexed under the key rewards.withdraw.address will have the following values stored and queryable:

  • AddrA
  • AddrB

To create a query for txs where address AddrA withdrew rewards: query.MustParse("tm.event = 'Tx' AND rewards.withdraw.address = 'AddrA'")

To create a query for txs where address AddrA withdrew rewards from source Y: query.MustParse("tm.event = 'Tx' AND rewards.withdraw.address = 'AddrA' AND rewards.withdraw.source = 'Y'")

To create a query for txs where AddrA transferred funds: query.MustParse("tm.event = 'Tx' AND transfer.sender = 'AddrA'")

The following queries would return no results: query.MustParse("tm.event = 'Tx' AND transfer.sender = 'AddrZ'") query.MustParse("tm.event = 'Tx' AND rewards.withdraw.address = 'AddrZ'") query.MustParse("tm.event = 'Tx' AND rewards.withdraw.source = 'W'")

See list of all possible events here https://godoc.org/github.com/tendermint/tendermint/types#pkg-constants

For complete query syntax, check out https://godoc.org/github.com/tendermint/tendermint/libs/pubsub/query.

import rpchttp "github.com/tendermint/rpc/client/http"
import "github.com/tendermint/tendermint/types"

client, err := rpchttp.New("tcp://0.0.0.0:26657", "/websocket")
if err != nil {
  // handle error
}

err = client.Start()
if err != nil {
  // handle error
}
defer client.Stop()
ctx, cancel := context.WithTimeout(context.Background(), 1 * time.Second)
defer cancel()
query := "tm.event = 'Tx' AND tx.height = 3"
txs, err := client.Subscribe(ctx, "test-client", query)
if err != nil {
  // handle error
}

go func() {
 for e := range txs {
   fmt.Println("got ", e.Data.(types.EventDataTx))
   }
}()

NOTE: if you're not reading events fast enough, Tendermint might terminate the subscription.

Query Parameters

queryRequired
string

query is a string, which has a form: "condition AND condition ..." (no OR at the moment). condition has a form: "key operation operand". key is a string with a restricted set of possible symbols ( \t\n\r\()"'=>< are not allowed). operation can be "=", "<", "<=", ">", ">=", "CONTAINS". operand can be a string (escaped with single quotes), number, date or time.

Exampletm.event = 'Tx' AND tx.height = 5

Responses

Unsubscribe from event on Websocket

GET/unsubscribe
client, err := rpchttp.New("tcp://0.0.0.0:26657", "/websocket")
if err != nil {
  // handle error
}

err := client.Start()
if err != nil {
  // handle error
}
defer client.Stop()
query := "tm.event = 'Tx' AND tx.height = 3"
err = client.Unsubscribe(context.Background(), "test-client", query)
if err != nil {
  // handle error
}

Query Parameters

queryRequired
string

query is a string, which has a form: "condition AND condition ..." (no OR at the moment). condition has a form: "key operation operand". key is a string with a restricted set of possible symbols ( \t\n\r\()"'=>< are not allowed). operation can be "=", "<", "<=", ">", ">=", "CONTAINS". operand can be a string (escaped with single quotes), number, date or time.

Exampletm.event = 'Tx' AND tx.height = 5

Responses

Unsubscribe from all events via WebSocket

GET/unsubscribe_all

Unsubscribe from all events via WebSocket

Responses