Dagger is the best way to get realtime updates from Ethereum Blockchain. It provides a way for your DApps and Backend system to get Ethereum blockchain events i.e. transactions, token transfers, receipts and logs in realtime over websocket or socket.

We maintain infrastructure for reliable and scalable realtime events. @maticnetwork/dagger is consumer library for Dagger project written in NodeJS. It uses Dagger server to get realtime updates from Ethereum Network.


# Using Yarn
yarn add @maticnetwork/dagger
# Using NPM
npm install @maticnetwork/dagger --save


Ethereum Network


Websocket: wss://mainnet.dagger.matic.network
Socket: mqtts://mainnet.dagger.matic.network (You can also use `ssl://` protocol)


Websocket: wss://kovan.dagger.matic.network
Socket: mqtts://kovan.dagger.matic.network (You can also use `ssl://` protocol)


Websocket: wss://ropsten.dagger.matic.network
Socket: mqtts://ropsten.dagger.matic.network (You can also use `ssl://` protocol)


Websocket: wss://goerli.dagger.matic.network
Socket: mqtts://goerli.dagger.matic.network (You can also use `ssl://` protocol)

Matic Network


Websocket: wss://matic-mainnet.dagger.matic.network
Socket: mqtts://matic-mainnet.dagger.matic.network (You can also use `ssl://` protocol)

Mumbai Testnet

Websocket: wss://mumbai-dagger.matic.today
Socket: mqtts://mumbai-dagger.matic.today (You can also use `ssl://` protocol)


  • Lets first create a npm project.
npm init -y
touch index.js
  • Now we can put following code snippet in index.js.
const Dagger = require('@maticnetwork/dagger')
// connect to correct dagger server, for receiving network specific events
// you can also use socket based connection
const dagger = new Dagger("wss://mainnet.dagger.matic.network")
// get new block as soon as it gets created
dagger.on('latest:block.number', result => {
console.log(`New block created: ${result}`)
  • Run index.js & you'll start receiving block number as soon as new block gets created.
node index.js


new Dagger(url)

Create dagger object

  • url is dagger server's address. Check network section for all available url values.


const dagger = new Dagger(<url>)

dagger.on(event, fn)

Subscribe to a topic

  • event is a String topic to subscribe to. event wildcard characters are supported (+ - for single level and # - for multi level)
  • fn - function (data, removed) fn will be executed when event occurred:
    • data data from event
    • removed flag saying if data is removed from blockchain due to re-organization.


dagger.on('latest:block.number', (res, flag) => { console.log(res, flag) })

dagger.once(event, fn)

Same as on but will be fired only once.


dagger.once('latest:block.number', (res, flag) => { console.log(res, flag) })

dagger.off(event, fn)

Unsubscribe from a topic

  • event is a String topic to unsubscribe from
  • fn - function (data, removed)


dagger.off('latest:block.number', (res, flag) => { console.log(res, flag) })


Create room out of dagger. room has to be one out of two values

  • latest
  • confirmed

room object has following methods:

  • on same as dagger on
  • once same as dagger once
  • off same as dagger off
const latestRoom = dagger.of('latest')
const confirmedRoom = dagger.of('confirmed')


Close the dagger, accepts the following options:

  • force: passing it to true will close the dagger right away. This parameter is optional.
dagger.end({force: true}) // immediate closing


Creates web3 contract wrapper to support Dagger.

  • First create a web3 contract object.
// web3 contract
const web3Contract = new web3.eth.Contract(abi, address)
  • Now we'll create a dagger contract wrapper on it.
// dagger contract
const contract = dagger.contract(web3Contract)
  • Time to filter out contract events
const filter = contract.events.Transfer({
filter: { from: "0x123456..." },
room: "latest"
  • Watching contract events
// watch
filter.watch((data, removed) => { console.log(data, removed) })
// or watch only once
filter.watchOnce((data, removed) => { console.log(data, removed) })
  • Stopping event watching
// stop watching


Every event has a room ∈ {latest, confirmed}.

  • latest : Events are fired immediately after block included in chain.
  • confirmed : Events are fired after 12 confirmations.

If you want to show updates on UI in your DApp, use latest events. It will help to make UI/UX better and user friendly.

Use confirmed events for irreversible tasks from server or on UI. Like sending email, notifications or allow user to do subsequent task on UI after one transaction gets confirmed.

Network Events

Ethereum eventWhen?removed flag
blockFor every new block createdYes
block.numberFor every new block number created
block.hashFor every new block hash createdYes
block/numberWhen particular block in future included in chainYes
addr/address/txOn every new transaction for addressYes
addr/address/tx/outOn every new outgoing transaction for addressYes
addr/address/tx/inOn every new incoming transaction for addressYes
tx/txIdWhen given txId included in blockYes
tx/txId/successWhen tx status is success (included in block) for txIdYes
tx/txId/failWhen tx fails (included in block) for txIdYes
tx/txId/receiptWhen receipt is generated (included in block) for txIdYes
addr/contractAddress/deployedWhen new contractAddress included in blockYes
log/contractAddressWhen new log generated for contractAddressYes
log/contractAddress/filter/topic1/topic2When new log with topic1 and topic2 generated for contractAddressYes

Dagger Events

Dagger EventWhen?args
connection.statusWhen connection status changesvalue: Boolean

Every event has to start with room:


For every new block

dagger.on("latest:block", result => {
console.log("Current block : ", result)


For every new block number

dagger.on("latest:block.number", result => {
console.log("Current block number : ", result)


For every new block hash

dagger.on("latest:block.hash", result => {
console.log("Current block hash : ", result)


When particular block X, in future included in chain

dagger.on("latest:block/X", result => {
console.log("Included in chain : ", result)


On every new transaction for address

dagger.on("latest:addr/{address}/tx", result => {
console.log("New Transaction : ", result)


dir is transaction direction ∈ {in, out}. address can be omitted to receive notification for any address.

On every new incoming transaction for address

dagger.on("latest:addr/{address}/tx/in", result => {
console.log("New Incoming Transaction : ", result)


status is txId's status ∈ {success, fail, receipt}. It can be kept empty too i.e. resulting into tx/{txId}, triggered when txId gets included in block.

When given txId included in block

dagger.on("latest:tx/{txId}", result => { console.log(result) })


When log generated for contractAddress

dagger.on("latest:log/{contractAddress}", result => {
console.log("New Log : ", result)


When new log with topic0, topic1 & topic2 generated for contractAddress

// Triggers when 1 GNT (Golem token) get transferred to Golem multisig wallet
dagger.on('latest:log/0xa74476443119a942de498590fe1f2454d7d4ac0d/filter/0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef/filter/+/0x7da82c7ab4771ff031b66538d2fb9b0b047f6cf9/#', console.log)
// Triggers when any amount of GNT (Golem token) get sent from Golem multisig wallet
dagger.on('latest:log/0xa74476443119a942de498590fe1f2454d7d4ac0d/filter/0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef/0x7da82c7ab4771ff031b66538d2fb9b0b047f6cf9/#', ...)
// Listen for every Golem token transfer (notice `#` at the end)
dagger.on('latest:log/0xa74476443119a942de498590fe1f2454d7d4ac0d/filter/0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef/#', ...)

Event names are case-sensitive. address, txId and topics must be in lowercase.

Note: You can use wildcard for events too. There are two type of wildcards: + (for single) and # (for multiple). Use with caution as it will fetch more data then you need, and can bombard with data to your DApp.

Test Dagger Server

This library consists woodendagger executable which is test dagger server on your local machine. So you can test with TestRPC.

Please do not use woodendagger in production. It's only for development purpose. It doesn't support removed flag.

$ woodendagger --url=https://mainnet.infura.io # or http://localhost:8545 for local json-rpc
# If you want to start dagger server on different ports,
# sockport: socket port for backend connection over TCP
# wsport: websocket port for frontend connection over websocket
$ woodendagger --url=http://localhost:8545 --sockport=1883 --wsport=1884
# To connect from dagger:
const dagger = new Dagger('mqtt://localhost:1883')


If you have any queries, feedback or feature requests, feel free to reach out to us on Telegram