# Events
This document describes working with zkSync events in more detail in a language-agnostic way. For a quick introduction to the zkSync events with examples in Javascript please read the quick introduction.
# Establishing the connection
The event server WebSocket URL for mainnet is wss://events.zksync.io
. You can find an example of client application
here.
# Event structure
After the connection is established, your client will receive messages about the events in the following format:
{
"block_number": 1100,
"type": "account",
"data": {
// Event-specific data
}
}
The block_number
is the number of the zkSync block in which the event happened The type
is the type of the event,
which is either account
, block
or the transaction
. The data
is the data specific to the event.
# Account events
The account events are events that are happening to zkSync accounts. There are four types of account events: create
,
delete
, update_balance
, change_pub_key_hash
. The delete
operation is currently disabled.
The data
for each account
event has the following format:
{
"update_type": "create",
"status": "committed",
"update_details": {
// details about account update
}
}
The status
field is equal to either committed
when the update was committed onchain or finalized
when the block
with such event has been verified with zero-knowledge proofs onchain.
Here are full examples of the account events:
{
"block_number": 25,
"type": "account",
"data": {
"update_type": "create",
"status": "committed",
"update_details": {
"account_id": 19,
"nonce": 0
}
}
}
{
"block_number": 24,
"type": "account",
"data": {
"update_type": "update_balance",
"status": "committed",
"update_details": {
"account_id": 18,
"nonce": 0,
"token_id": 0,
"new_balance": "2000000000000000000000"
}
}
}
{
"block_number": 27,
"type": "account",
"data": {
"update_type": "change_pub_key_hash",
"status": "committed",
"update_details": {
"account_id": 20,
"nonce": 1,
"new_pub_key_hash": "sync:8af45346a8456d7a1fc26507ce1699329efcb4c3"
}
}
}
# Block events
The block events are events notifying whether the block has been committed or finalized. Such events have the following structure:
{
"block_number": 27,
"type": "block",
"data": {
"status": "committed",
"block_number": 27,
"new_state_root": "sync-bl:194d9ce3c118867f6132c2f92bbb602b230d9d777372f6198801b0699afecbc0",
"block_size": 32,
"commit_tx_hash": "0xde56e5a61e4588d9c25246a841f05675b9b10cb26def279475580fe58a0b443f",
"committed_at": "2021-05-20T11:32:35.433853Z"
}
}
The status
field is equal to either committed
when the update was committed onchain or finalized
when the block
with such event has been verified with zero-knowledge proofs onchain. It can also be equal to reverted
if the block
has been reverted. A block that was finalized can never be reverted.
Here is an example of a finalized
block event:
{
"block_number": 24,
"type": "block",
"data": {
"status": "finalized",
"block_number": 24,
"new_state_root": "sync-bl:15b15f8c1b20aff7da841a77250c3ada37997e79beded3ea65641f7e0db7239a",
"block_size": 32,
"commit_tx_hash": "0x274e78480e51b8eb4186effab2f1c940914984eecd224675155eec26e359820d",
"verify_tx_hash": "0xb670313796467bd97d8ed40071da5c67bc2ac123d435c0131ea9fec2894c03c0",
"committed_at": "2021-05-20T11:32:26.432639Z",
"verified_at": "2021-05-20T11:32:37.443933Z"
}
}
# Transacton events
The transaction events notify about transactions being committed or finalized. They notify about both L2 transactions
and L1 priority operations. The data
for each event looks the following way:
{
"tx_hash": "0xf62c8a0bc8d0ead1abbd3b8772bb27973e40e42027f06ab3952e7dc29cb69c27",
"account_id": 18,
"token_id": 0,
"block_number": 24,
"tx": {
// Tx data unique for each transaction type
},
"status": "committed",
"created_at": "2021-05-20T11:32:26.232439Z"
}
The status
field is equal to either committed
when the transaction was committed onchain or finalized
when the
block with such event has been verified with zero-knowledge proofs onchain. It can also be equal to reverted
if the
transaction was invalid.
Here are a few examples for transaction events:
# Transfer
{
"block_number": 25,
"type": "transaction",
"data": {
"tx_hash": "sync-tx:5237455cb49ef063a81b77f1848f4ed46196ff2f8b55faa945c117d7d5282159",
"account_id": 18,
"token_id": 0,
"block_number": 25,
"tx": {
"to": "0x675c03cadf1528af6260f1f1be1f557bbcefbb05",
"fee": "31000000000000",
"from": "0xdeaafff966f14498d1c9cd5561c92c914564aef9",
"type": "Transfer",
"nonce": 1,
"token": 0,
"amount": "10000000000000000000",
"accountId": 18,
"signature": {
"pubKey": "4a2ef46ea7765c77c8ca84cfb0597a527985ee51b5e5be28531dbade85ee1498",
"signature": "366ccd69f9183c2b78d0448bf0e552b95a4f47f343d9dff7ba60537c50efab9b8d18b4693f8f8ef9787e6e1d60a6cecdc21c9871d59d8a38935458ba12495f00"
},
"validFrom": 0,
"validUntil": 4294967295
},
"status": "finalized",
"created_at": "2021-05-20T11:32:28.840918Z"
}
}
# ChangePubKey
{
"block_number": 27,
"type": "transaction",
"data": {
"tx_hash": "sync-tx:b78eaacff2c86ec9fbf6e4e11d8a911cb3c1c8be41b3af14eeec1fb242d34f7e",
"account_id": 20,
"token_id": 0,
"block_number": 27,
"tx": {
"fee": "0",
"type": "ChangePubKey",
"nonce": 0,
"account": "0xf32b6fb3332b7b3edf30e1e469f581974bd8b378",
"feeToken": 0,
"accountId": 20,
"newPkHash": "sync:8af45346a8456d7a1fc26507ce1699329efcb4c3",
"signature": {
"pubKey": "0732cb8a917b3c48fbaa39a6da760c50e972ee014033eb511237a43a221ef480",
"signature": "b7ea639a0924bc62437e9732956b90531b0f1dee52d17e6b06dd56bf6c9df80ee968b73b55ed350579e298d0d5d5018bc9bd5238fe1a7aca91c6a63ba0b9cf04"
},
"validFrom": 0,
"validUntil": 4294967295,
"ethAuthData": {
"type": "Onchain"
},
"ethSignature": null
},
"status": "finalized",
"created_at": "2021-05-20T11:32:35.279076Z"
}
}
# Withdraw
{
"block_number": 28,
"type": "transaction",
"data": {
"tx_hash": "sync-tx:37f1adc19bd78cecc56bcdb3453d7cfd340434757f1d9bbe56dddb0d2de66047",
"account_id": 22,
"token_id": 0,
"block_number": 28,
"tx": {
"to": "0x1cf9517f403235c7e871c5d96e224326a404e12d",
"fee": "141400000000000",
"fast": false,
"from": "0x1cf9517f403235c7e871c5d96e224326a404e12d",
"type": "Withdraw",
"nonce": 1,
"token": 0,
"amount": "10000000000000000000",
"accountId": 22,
"signature": {
"pubKey": "71b2ec034927306a016374419f806442a84af73e175865961f6b627adbc51b24",
"signature": "ae923a804ef5999dba0d0c017aa4417b93b36fe24e1fe5d394b2a8b390e45b98f5e08dce47c7a1b675db9c0fab5bf4ab1b0c6059bb9d9fe7cb134deb398e2705"
},
"validFrom": 0,
"validUntil": 4294967295
},
"status": "committed",
"created_at": "2021-05-20T11:32:36.873472Z"
}
}
# ForcedExit
{
"block_number": 29,
"type": "transaction",
"data": {
"tx_hash": "sync-tx:e43867aaa909ea52879428e28836c9e162951a60bb9ad94d1c03c432017bbbb6",
"account_id": 20,
"token_id": 0,
"block_number": 29,
"tx": {
"fee": "204300000000000",
"type": "ForcedExit",
"nonce": 6,
"token": 0,
"target": "0x3a9d7cced6e600eacf5e70a7f55b5d458e1ea5f8",
"signature": {
"pubKey": "0732cb8a917b3c48fbaa39a6da760c50e972ee014033eb511237a43a221ef480",
"signature": "52af07b1d5ca8a61dd916ae31ac199f8e645d7f2be696c151a96debed0429a8476047fe4f93390ac6825b6fef816268b24fc1aee07562659fa7dc0c5bb6edc04"
},
"validFrom": 0,
"validUntil": 4294967295,
"initiatorAccountId": 20
},
"status": "committed",
"created_at": "2021-05-20T11:32:38.657075Z"
}
}
# Deposit
{
"block_number": 27,
"type": "transaction",
"data": {
"tx_hash": "0x4bde9a0ab7eff4850799a0961afadad2d4914cfa332a5a7a140a6a9b8b5c57fc",
"account_id": 22,
"token_id": 2,
"block_number": 27,
"tx": {
"type": "Deposit",
"account_id": 22,
"priority_op": {
"to": "0x1cf9517f403235c7e871c5d96e224326a404e12d",
"from": "0x36615cf349d7f6344891b1e7ca7c72883f5dc049",
"token": 2,
"amount": "2000000000000000000000"
}
},
"status": "finalized",
"created_at": "2021-05-20T11:32:33.232676Z"
}
}
# FullExit
{
"block_number": 41,
"type": "transaction",
"data": {
"tx_hash": "0x7d83f56d243630afd40292e2d8ca307ca5287d82d1324e2795d85a28a05694b6",
"account_id": 145,
"token_id": 2,
"block_number": 41,
"tx": {
"type": "FullExit",
"priority_op": {
"token": 2,
"account_id": 145,
"eth_address": "0x905ef38b8b2fdedfab9a77fdde94c577d66fd91d"
},
"withdraw_amount": null
},
"status": "committed",
"created_at": "2021-05-20T11:34:45.232211Z"
}
}
# Filters
After the connection is established, the client needs to send the filter for the events. A filter is a JSON object of the following type:
{
"account": {
// `account` events filter
},
"block": {
// `block` events filter
},
"transaction": {
// `transaction` events filter
}
}
Some of the fields may be omitted. For instance, the following filter tells that the client wants to receive only
account
events of a certain type.
{
"account": {
// account filter
}
}
If the filter object is empty, it means "no filter". Here are a few examples:
// Here we receive all the `account` events from zkSync
{
"account": {}
}
// Here we receive all the `account` and `block` events from zkSync
{
"account": {},
"block": {}
}
// Here we receive all the `account`, `block`, and `transaction` events
// This is the same as receiving all events
{
"account": {},
"block": {},
"transaction": {}
}
// Empty object means we want to receive all events
{}
# Filter account events
The account
events can be filtered by several parameters:
{
"accounts": [],
"tokens": [],
"status": "committed"
}
The accounts
parameter is an array of account ids, the events about which should be sent to the client. If not
specified, events about any account will be sent.
The tokens
parameter is an array of token ids, which were involved in the account update.
The status
is the status of updates that need to be sent.
# Filter block events
block
events can only be filtered by the status of the block:
{
"status": "finalized"
}
# Filter transaction events
The transaction
events can be filtered by several parameters:
"types": [],
"accounts": [],
"tokens": [],
"status": "finalized",
The accounts
, tokens
, and status
parameters have the same meaning as for the account
events filters.
The types
is an array of types of transaction
events about which you wish to receive. The following transaction
types are supported: Transfer
, Withdraw
, ChangePubKey
, ForcedExit
, FullExit
, Deposit
.
# Examples
Here are some additional examples of filtering:
// Here we are only interested in the committed events about
// accounts with ids 1,2,3 which change their balance of token with id 0 (ETH)
{
"account": {
"status": "committed",
"accounts": [1, 2, 3],
"tokens": [0]
}
}
// Here we are only interested in the finalized events of any account
// and any block verification events any transaction events (both committed and finalized)
{
"account": {
"status": "finalized"
},
"block": {
"status": "reverted"
},
"transaction": {}
};
# Note on stability
Technically the committed blocks may be reverted and the transactions inside them will be reverted as well. This happens
very rarely, but if your client relies on committed events, some precautious measures should be taken. If a block is
reverted the client will be notified with an appropriate block
event, but it will not be notified about the individual
transaction
events and the account
events to be reverted as well. It is recommended that if you rely on committed
events, then you also keep track of the block
events to know if a block was reverted.
If you want to receive events only about final transactions, then you should accept only finalized
events. The
finalized
blocks can never be reverted as it is enforced by an Ethereum smart contract.
← Environments API v0.1 →