đŸĒŸExternal Events


Guardian will publish a number of events to the NATS server to hook into those events, which extends the function that is suitable to the solution.

Hooks to an external event

To hook into Guardian events, we need to have a client, that is connected to the same NATS instance with Guardian and implement the response function for a specific event.

Below is the sample for .NodeJs and in the case of other languages please refer to Nats.io for complete documentation.

publish/subscribe to events

The events with type=publish is publish/subscribe pattern so that the same message can be received by multiple clients. If there are multiple clients make sure it is handled by duplicate message processing.

import { connect, JSONCodec } from "nats";

(async () => {
  const nc = await connect({ servers: "localhost:4222" });

  const c = JSONCodec();
  const sub = nc.subscribe("externals-events.ipfs_added_file");

  (async () => {
    for await (const m of sub) {
      console.log(`[${sub.getProcessed()}]`, c.decode(m.data));
    console.log("subscription closed");

To get more information please click https://github.com/nats-io/nats.js#publish-and-subscribe

request/reply events

Some event has a type=request for which we need to subscribe and respond to the event.


For the before/after IPFS event, if the listener responds with an error then the IPFS service will be skipped and upload/respond to the actual content. This same scenario also happens when we do not have a listener to an event. For example, we can use this to encrypt/decrypt IPFS content file

const responseToIpfsEvent = (type: string, cb: (data: Buffer) => Buffer) => {
        const sub = nc.subscribe(type);
        console.log("√ Listening to IPFS event: %s", type);
        (async () => {
            for await (const m of sub) {
                console.log(`[${sub.getProcessed()} - ${m.subject}]`);
                try {
                    const payload = c.decode(m.data) as any;
                    const body = cb(Buffer.from(payload.content, 'base64'));
                    const responseMessage = { body: body.toString('base64') }
                    const archResponse = zlib.deflateSync(JSON.stringify(responseMessage)).toString('binary');
                } catch (e) {
                    // It is important that you should handle the content to make sure that is your encrypted/decrypted, skip if that is system ipds file
                    const archResponse = zlib.deflateSync(JSON.stringify({ error: e.message })).toString('binary');

            console.log("Subscription closed");

External events list




{cid, url}

Event is published when an IPFS file is added



{ tokenId, tokenValue, memo }

When token is minted successfully



{message, type, attributes}

When an error is sent to logger service



{blockType, blockTag, uuid ,data, result}

After runAction is finished, events are called by these blocks:

  1. aggregateDocumentBlock

  2. mintDocumentBlock

  3. sendToGuardianBlock

  4. timerBlock after runAction finish




The base64 of the content (buffer) to be hooked and modified




The base64 of the content (buffer) to be modified/processed


This example demonstrates the implementation of encryption/decryption of simple IPFS content.

Please refer to https://github.com/hashgraph/guardian/blob/main/common/src/mq/sample-external-client.ts

Last updated