ZeroMQ event plugin

Subscribe to TRON on-chain events directly from a Fullnode's built-in ZeroMQ publisher — no plugin install required, no external storage. Best for lightweight in-network consumers.

📘

Prerequisites

The java-tron Fullnode includes a built-in ZeroMQ publisher (TIP-28). Unlike the Kafka and MongoDB plugins, the ZeroMQ path requires no external plugin JAR — the node itself opens a TCP pub-sub socket that any ZeroMQ subscriber can connect to.

This is the lowest-setup-cost option for event subscription. It does not persist events anywhere; consumers see events live as the node emits them, and miss anything published while they are disconnected. Use ZeroMQ when you have a single in-network consumer or for short-lived subscriptions during development. For durability or replay, use the Kafka plugin; for indexed storage, use the MongoDB plugin.

Configure the node

In config.conf, enable the native message queue under event.subscribe:

event.subscribe = {
  enable = true             // Enables event subscription
  native = {
    useNativeQueue = true     // true = built-in ZeroMQ; false = use external plugin
    bindport = 5555           // TCP port the publisher binds to
    sendqueuelength = 1000    // max queued messages before back-pressure drops
  }

  // ...

  topics = [
    {
      triggerName = "block"   // event type — see Event subscription overview for the full list
      enable = true
      topic = "block"         // external-plugin topic; native ZeroMQ does not use it to rename the topic
    },
    // additional triggers...
  ]
}

Field reference:

FieldMeaning
event.subscribe.enableMaster switch for event subscription. It defaults to false; set it to true to enable event subscription.
native.useNativeQueuetrue enables the built-in ZeroMQ; false falls back to the external plugin path.
native.bindportTCP port the publisher binds. Subscribers connect to tcp://<node-ip>:<bindport>.
native.sendqueuelengthMaximum buffered messages. When a subscriber consumes too slowly and the queue fills, additional messages are dropped — sized to your expected event rate plus headroom.
topicsSelects which events to publish through triggerName and enable. With native ZeroMQ, topic does not rename the published topic; that field is used by external plugins such as Kafka and MongoDB. See the event subscription overview for the available triggerName values.

Native ZeroMQ uses java-tron's runtime trigger names as subscription topics rather than the configured triggerName or topic value:

Configured triggerNameZeroMQ subscription topic
blockblockTrigger
transactiontransactionTrigger
contractlogcontractLogTrigger
contracteventcontractEventTrigger
soliditysolidityTrigger
soliditylogsolidityLogTrigger
solidityeventsolidityEventTrigger

Start the node

Event subscription is disabled by default. After confirming that
event.subscribe.enable = true is set in config.conf, start the node:

java -jar FullNode.jar -c config.conf

The node starts a ZeroMQ publisher bound to the configured port. From this point, any subscriber connecting to tcp://<node-ip>:<bindport> and matching one of the configured topics receives events live.

Subscribe with Node.js

Install the ZeroMQ client library:

npm install zeromq

Write a subscriber that connects, subscribes to the blockTrigger topic, and logs each event:

// subscriber.js (zeromq v6)
const { Subscriber } = require("zeromq");

async function run() {
  const sock = new Subscriber();
  sock.connect("tcp://127.0.0.1:5555");
  sock.subscribe("blockTrigger");
  console.log("Subscriber connected to port 5555");

  for await (const [topic, message] of sock) {
    console.log(
      "received a message related to:",
      topic.toString(),
      ", containing message:",
      message.toString()
    );
  }
}

run().catch(console.error);

Run it:

node subscriber.js
# Subscriber connected to port 5555

ZeroMQ pub-sub does not provide authentication or transport encryption. In production, restrict access to this port with a firewall or a private network.

When the node produces a new block, the subscriber receives the event:

received a message related to: blockTrigger, containing message: {"timeStamp":1678343709000,"triggerName":"blockTrigger","blockNumber":1361,"blockHash":"00000000000005519b3995cd638753a862c812d1bda11de14bbfaa5ad3383280","transactionSize":0,"latestSolidifiedBlockNumber":1361,"transactionList":[]}
received a message related to: blockTrigger, containing message: {"timeStamp":1678343712000,"triggerName":"blockTrigger","blockNumber":1362,"blockHash":"0000000000000552d53d1bdd9929e4533a983f14df8931ee9b3bf6d6c74a47b0","transactionSize":0,"latestSolidifiedBlockNumber":1362,"transactionList":[]}

Other ZeroMQ language bindings (Python pyzmq, Go pebbe/zmq4, Java jeromq) work the same way: connect to the publisher, subscribe to a ZeroMQ topic from the table above, and decode each message as UTF-8 JSON.


Related resources