SNS Notifications

Learn how to get real-time push notifications from the Lens protocol.


Lens utilizes Amazon Simple Notification Service (SNS) to push notification events, enabling easy integration for third-party providers. This service merely broadcasts data from the chain to your server without applying any filters.

Initial Setup

To set up SNS notifications, you need to provide the Lens Protocol team with two webhook URLs for SNS - one for Mainnet notifications and another for Testnet notifications. These URLs will be used to authenticate and initiate a handshake request. Ensure your code is configured to listen for incoming notifications. An example is provided below.

To get in touch with the Lens Protocol team, join the Lens Developer Garden Telegram group.

The example below demonstrates how to create a webhook using Express.js.

import bodyParser from "body-parser";import express from "express";import fetch from "node-fetch";
const app = express();const port = 8080;
app.use(bodyParser.urlencoded({ extended: false }));app.use(bodyParser.json());
app.post("/lens/notifications", async (req, res) => {  const buffers = [];
  for await (const chunk of req) {    buffers.push(chunk);  }
  const data = Buffer.concat(buffers).toString();  // example https://docs.aws.amazon.com/connect/latest/adminguide/sns-payload.html  const payload = JSON.parse(data);
  // if you already done the handshake you will get a Notification type  // example below: https://docs.aws.amazon.com/sns/latest/dg/sns-message-and-json-formats.html  // {  //   "Type" : "Notification",  //   "MessageId" : "22b80b92-fdea-4c2c-8f9d-bdfb0c7bf324",  //   "TopicArn" : "arn:aws:sns:us-west-2:123456789012:MyTopic",  //   "Subject" : "My First Message",  //   "Message" : "Hello world!",  //   "Timestamp" : "2012-05-02T00:54:06.655Z",  //   "SignatureVersion" : "1",  //   "Signature" : "EXAMPLEw6JRN...",  //   "SigningCertURL" : "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem",  //   "UnsubscribeURL" : "https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe SubscriptionArn=arn:aws:sns:us-west-2:123456789012:MyTopic:c9135db0-26c4-47ec-8998-413945fb5a96"  // }  if (payload.Type === "Notification") {    console.log("SNS message is a notification ", payload);    console.log("------------------------------------------------------");    console.log("------------------------------------------------------");    console.log("------------------------------------------------------");    res.sendStatus(200);    return;  }
  // only need to do this the first time this is doing an handshake with the sns client  // example below: https://docs.aws.amazon.com/sns/latest/dg/sns-message-and-json-formats.html  // {  //   "Type" : "SubscriptionConfirmation",  //   "MessageId" : "165545c9-2a5c-472c-8df2-7ff2be2b3b1b",  //   "Token" : "2336412f37...",  //   "TopicArn" : "arn:aws:sns:us-west-2:123456789012:MyTopic",  //   "Message" : "You have chosen to subscribe to the topic arn:aws:sns:us-west-2:123456789012:MyTopic.\nTo confirm the subscription, visit the SubscribeURL included in this message.",  //   "SubscribeURL" : "https://sns.us-west-2.amazonaws.com/?Action=ConfirmSubscription&TopicArn=arn:aws:sns:us-west-2:123456789012:MyTopic&Token=2336412f37...",  //   "Timestamp" : "2012-04-26T20:45:04.751Z",  //   "SignatureVersion" : "1",  //   "Signature" : "EXAMPLEpH+DcEwjAPg8O9mY8dReBSwksfg2S7WKQcikcNKWLQjwu6A4VbeS0QHVCkhRS7fUQvi2egU3N858fiTDN6bkkOxYDVrY0Ad8L10Hs3zH81mtnPk5uvvolIC1CXGu43obcgFxeL3khZl8IKvO61GWB6jI9b5+gLPoBc1Q=",  //   "SigningCertURL" : "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem"  // }  if (payload.Type === "SubscriptionConfirmation") {    const url = payload.SubscribeURL;    const response = await fetch(url);    if (response.status === 200) {      console.log("Subscription confirmed");      console.log("------------------------------------------------------");      console.log("------------------------------------------------------");      console.log("------------------------------------------------------");      res.sendStatus(200);      return;    } else {      console.error("Subscription failed");      res.sendStatus(500);      return;    }  }
  console.log("Received message from SNS", payload);
  // if it gets this far it is a unsubscribe request  // {  //   "Type" : "UnsubscribeConfirmation",  //   "MessageId" : "47138184-6831-46b8-8f7c-afc488602d7d",  //   "Token" : "2336412f37...",  //   "TopicArn" : "arn:aws:sns:us-west-2:123456789012:MyTopic",  //   "Message" : "You have chosen to deactivate subscription arn:aws:sns:us-west-2:123456789012:MyTopic:2bcfbf39-05c3-41de-beaa-fcfcc21c8f55.\nTo cancel this operation and restore the subscription, visit the SubscribeURL included in this message.",  //   "SubscribeURL" : "https://sns.us-west-2.amazonaws.com/?Action=ConfirmSubscription&TopicArn=arn:aws:sns:us-west-2:123456789012:MyTopic&Token=2336412f37fb6...",  //   "Timestamp" : "2012-04-26T20:06:41.581Z",  //   "SignatureVersion" : "1",  //   "Signature" : "EXAMPLEHXgJm...",  //   "SigningCertURL" : "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem"  // }});
app.listen(port, () =>  console.log("SNS notification listening on port " + port + "!"));

Signatures

It's important to verify the authenticity of any notification, subscription confirmation, or unsubscribe confirmation message sent by Amazon SNS.

You can do this by using the information contained in the Amazon SNS message to recreate the string to sign and the signature. By matching the recreated signature with the one sent by Amazon SNS, you can verify the message's contents.

For more information, refer to the Verifying the signatures of Amazon SNS messages guide.

const bent = require("bent");const getBuffer = bent("buffer");const crypto = require("crypto");const debug = require("debug")("verify-aws-sns-signature");const parseUrl = require("parse-url");const assert = require("assert");
async function validatePayload(payload) {  const {    SigningCertURL,    Signature,    Message,    MessageId,    SubscribeURL,    Subject,    Timestamp,    Token,    TopicArn,    Type,  } = payload;
  // validate SubscribeURL  const url = parseUrl(SigningCertURL);  assert.ok(    /^sns\.[a-zA-Z0-9\-]{3,}\.amazonaws\.com(\.cn)?$/.test(url.resource),    `SigningCertURL host is not a valid AWS SNS host: ${SigningCertURL}`  );
  try {    debug(`retrieving AWS certificate from ${SigningCertURL}`);
    const x509 = await getBuffer(SigningCertURL);    const publicKey = crypto.createPublicKey(x509);    const signature = Buffer.from(Signature, "base64");    const stringToSign = (      "Notification" === Type        ? [            { Message },            { MessageId },            { Subject },            { Timestamp },            { TopicArn },            { Type },          ]        : [            { Message },            { MessageId },            { SubscribeURL },            { Timestamp },            { Token },            { TopicArn },            { Type },          ]    ).reduce((acc, el) => {      const key = el.keys()[0];      acc += key + "\n" + el[key] + "\n";    }, "");
    debug(`string to sign: ${stringToSign}`);    const verified = crypto.verify(      "sha1WithRSAEncryption",      Buffer.from(stringToSign, "utf8"),      publicKey,      signature    );    debug(      `signature ${verified ? "has been verified" : "failed verification"}`    );    return verified;  } catch (err) {    return false;  }}
module.exports = { validatePayload };

Message Types

The Message field is the key property to pay attention to. This field contains the information that will be pushed to SNS. It is always an object, presented as a stringified JSON string.

All messages will adhere to the following structure:

export interface PublishMessage {  type: SnsMessageTypes;  data: any;}

The type corresponds to the response type that will be defined later in this guide.


Events

Referring to the Message structure outlined above, this section will focus on the data field. All examples will demonstrate the response type for this field, not the entire SNS object. For clarity, the guide will present JSON examples as if the Message has already been parsed (e.g., via JSON.parse).

This guide assumes that you already understand the Lens Primitives, the events emitted by the protocol, and the purpose of each data property.

Profile Events

FOLLOW_NFT_DEPLOYED

This event is triggered when the Follow NFT contract is deployed. Keep in mind that Follow NFT contracts are lazy-loaded, meaning they are only deployed when the first follow occurs.

interface Response {  profileId: string;  followNFT: string;  timestamp: number;  logIndex: number;  txHash: string;  txIndex: number;}

METADATA_PROFILE_COMPLETE

A notification is emitted when the profile metadata has been snapshotted and indexed by the API.

For the exact metadata type definition, refer to the @lens-protocol/metadata package.

import { ProfileMetadata } from "@lens-protocol/metadata";import { ProfileMetadata as LegacyProfileMetadata } from "@lens-protocol/metadata/legacy";
interface Response {  profileId: string;  // the metadata extracted for you  metadata: ProfileMetadata | LegacyProfileMetadata;  // the snapshot s3 url for fast fetching  snapshotLocation: string;}

METADATA_PROFILE_FAILED

A notification is emitted when the snapshotting of the profile metadata fails. This could occur if the metadata is invalid or unreachable. The snapshot process will retry periodically for 20 minutes before marking it as failed. However, if the metadata is invalid, it won't retry and will immediately mark it as failed, providing an error reason.

interface Response {  profileId: string;  // the reason why it failed  errorReason: string;  // if it was unreachable for 20 minutes  timeoutRequest: boolean;}

PROFILE_BLOCKED

This event is emitted when one profile blocks another profile.

interface Response {  byProfileId: string;  idOfProfileBlocked: string;  transactionExecutor: string;  timestamp: string;  logIndex: number;  txHash: string;  txIndex: number;}

PROFILE_UNBLOCKED

This event is emitted when one profile unblocks another profile.

interface Response {  byProfileId: string;  idOfProfileUnblocked: string;  transactionExecutor: string;  timestamp: number;  logIndex: number;  txHash: string;  txIndex: number;}

PROFILE_CREATED

This event is emitted when a new profile is created.

interface Response {  profileId: string;  creator: string;  to: string;  timestamp: number;  logIndex: number;  txHash: string;  txIndex: number;}

PROFILE_CREATOR_ALLOWLISTED

This event is emitted when a profile creator is added to the allowlist.

interface Response {  profileCreator: string;  allowlisted: boolean;  timestamp: number;  logIndex: number;  txHash: string;  txIndex: number;}

PROFILE_FOLLOWED

This event is emitted when a profile starts following another profile.

interface Response {  followerProfileId: string;  idOfProfileFollowed: string;  followTokenIdAssigned: string;  followModuleData: string;  processFollowModuleReturnData: string;  transactionExecutor: string;  timestamp: number;  logIndex: number;  txHash: string;  txIndex: number;}

PROFILE_UNFOLLOWED

This event is emitted when a profile stops following another profile.

interface Response {  unfollowerProfileId: string;  idOfProfileUnfollowed: string;  transactionExecutor: string;  timestamp: number;  logIndex: number;  txHash: string;  txIndex: number;}

PROFILE_GUARDIAN_STATE_CHANGED

This event is emitted when the state of the profile guardian changes.

interface Response {  owner: string;  enabled: boolean;  tokenGuardianDisablingTimestamp: number;  timestamp: number;  logIndex: number;  txHash: string;  txIndex: number;}

PROFILE_HANDLE_LINKED

This event is emitted when a handle is linked to a profile.

Type
interface TokenInfo {  id: string;  collection: string;}
interface Response {  handle: TokenInfo;  token: TokenInfo;  transactionExecutor: string;  timestamp: number;  logIndex: number;  txHash: string;  txIndex: number;}

PROFILE_HANDLE_MINTED

This event is emitted when a new handle is minted.

Type
interface Response {  handle: string;  namespace: string;  handleId: string;  to: number;  timestamp: number;  logIndex: number;  txHash: string;  txIndex: number;}

PROFILE_HANDLE_UNLINKED

This event is emitted when a handle is unlinked from a profile.

Type
interface TokenInfo {  id: string;  collection: string;}
interface Response {  handle: TokenInfo;  token: TokenInfo;  transactionExecutor: string;  timestamp: number;  logIndex: number;  txHash: string;  txIndex: number;}

PROFILE_MANAGER_CHANGED

This event is emitted when the profile manager changes.

Type
interface Response {  delegatorProfileId: string;  configNumber: string;  delegatedExecutors: string[];  approvals: boolean[];  timestamp: number;  logIndex: number;  txHash: string;  txIndex: number;}

PROFILE_MANAGER_CONFIG_APPLIED

This event is emitted when the profile manager configuration has been applied.

Type
interface Response {  delegatorProfileId: string;  configNumber: string[];  timestamp: number;  logIndex: number;  txHash: string;  txIndex: number;}

PROFILE_METADATA_SET

This event is emitted when someone updates the metadata for a profile.

Please note that the emission of this event does not guarantee that the updated data adheres to the Metadata Standards. The update will be indexed, but if the data does not comply with the Metadata Standards, it will not be updated and made available in the API.

You can use the METADATA_PROFILE_COMPLETE and METADATA_PROFILE_FAILED notifications to monitor these states.

interface Response {  profileId: string;  // the metadata contains normally an IPFS or weblink which resolves the metadata  metadata: string;  transactionExecutor: string;  timestamp: number;  logIndex: number;  txHash: string;  txIndex: number;}

PROFILE_TRANSFERRED

This event is emitted when the ownership of a profile is transferred to a different wallet.

Type
interface Response {  from: string;  to: string;  tokenId: string;  timestamp: number;  logIndex: number;  txHash: string;  txIndex: number;}

PROFILE_REPORTED

This event is emitted when a profile is reported.

Type
interface Response {  profileId: string;  reporterProfileId: string;  timestamp: number;  reason: string;  subreason: string;  additionalComments: string | null;}

Publication Events

POST_CREATED

This event is emitted when a new post is created.

Please note that the emission of this event does not guarantee that the posted data adheres to the Metadata Standards. The post will be indexed, but if the data does not comply with the Metadata Standards, it will not be updated and made available in the API.

You can use the METADATA_PUBLICATION_COMPLETE and METADATA_PUBLICATION_FAILED notifications to monitor these states.

interface Response {  // pub id are counters of the publication so they clash with profiles  // on the server we build up our own publication id to allow it to be searchable  // this is {profileId}-{pubId} and is used in all our API calls and responses  serverPubId: string;  isMomoka: boolean;  // will be defined if its a momoka post  momokaProof?: string;
  postParams: {    profileId: string;    contentURI: string;    // will be empty array if not action modules set    actionModules: string[];    // will be empty array if not action modules set    actionModulesInitDatas: string[];    // will null if not set    referenceModule: string | null;    // will be null if not set    referenceModuleInitData: string | null;  };  pubId: string;  // will be empty array if not action modules set  actionModulesInitReturnDatas: string[];  // will be empty array if not action modules set  referenceModuleInitReturnData: string | null;  transactionExecutor: string;  timestamp: number;  // will not be defined if its a momoka post  logIndex?: number;  txHash?: string;  txIndex?: number;}

COMMENT_CREATED

This event is emitted when someone comments on a publication.

Please note that the emission of this event does not guarantee that the comment data adheres to the Metadata Standards. The comment will be indexed, but if the data does not comply with the Metadata Standards, it will not be updated and made available in the API.

You can use the METADATA_PUBLICATION_COMPLETE and METADATA_PUBLICATION_FAILED notifications to monitor these states.

interface Response {  // pub id are counters of the publication so they clash with profiles  // on the server we build up our own publication id to allow it to be searchable  // this is {profileId}-{pubId} and is used in all our API calls and responses  serverPubId: string;  serverPubIdPointer: string;  isMomoka: boolean;  // will be defined if its a momoka comment  momokaProof?: string;  commentParams: {    profileId: string;    contentURI: string;    pointedProfileId: string;    pointedPubId: string;    referrerProfileIds: string[];    referrerPubIds: string[];    // will be empty array if not action modules set    actionModules: string[];    // will be empty array if not action modules set    actionModulesInitDatas: string[];    // will null if not set    referenceModule: string | null;    // will be null if not set    referenceModuleData: string | null;    // will be null if not set    referenceModuleInitData: string | null;  };  pubId: string;  // will be empty array if not action modules set  actionModulesInitReturnDatas: string[];  // will null if not set  referenceModuleInitReturnData: string | null;  // will null if not set  referenceModuleReturnData: string | null;  transactionExecutor: string;  timestamp: number;  // will not be defined if its a momoka comment  logIndex?: number;  txHash?: string;  txIndex?: number;}

MIRROR_CREATED

This event is emitted when a profile mirrors a publication, inheriting the mirrored publication's metadata.

Please note that the emission of this event does not guarantee that the mirrored publication metadata adheres to the Metadata Standards. The mirrored publication will be indexed, but if the data does not comply with the Metadata Standards, it will not be updated and made available in the API.

You can use the METADATA_PUBLICATION_COMPLETE and METADATA_PUBLICATION_FAILED notifications to monitor these states.

Please note that a Mirror differs from a Post, Comment, or Quote because it doesn't have any associated metadata. To understand when it was snapshotted and made viewable, you must link the mirrored publication to the mirror itself.

interface Response {  // pub id are counters of the publication so they clash with profiles  // on the server we build up our own publication id to allow it to be searchable  // this is {profileId}-{pubId} and is used in all our API calls and responses  serverPubId: string;  serverPubIdPointer: string;  isMomoka: boolean;  // will be defined if its a momoka mirror  momokaProof?: string;  mirrorParams: {    profileId: string;    pointedProfileId: string;    pointedPubId: string;    referrerProfileIds: string[];    referrerPubIds: string[];    // will be null if not set    referenceModuleData: string | null;  };  pubId: string;  // will null if not set  referenceModuleReturnData: string | null;  transactionExecutor: string;  timestamp: number;  // will not be defined if its a momoka mirror  logIndex?: number;  txHash?: string;  txIndex?: number;}

QUOTE_CREATED

This event is emitted when someone quotes a publication.

Please note that the emission of this event does not guarantee that the quoted data adheres to the Metadata Standards. The quote will be indexed, but if the data does not comply with the Metadata Standards, it will not be updated and made available in the API.

You can use the METADATA_PUBLICATION_COMPLETE and METADATA_PUBLICATION_FAILED notifications to monitor these states.

interface Response {  // pub id are counters of the publication so they clash with profiles  // on the server we build up our own publication id to allow it to be searchable  // this is {profileId}-{pubId} and is used in all our API calls and responses  serverPubId: string;  serverPubIdPointer: string;  isMomoka: boolean;  // will be defined if its a momoka quote  momokaProof?: string;  quoteParams: {    profileId: string;    contentURI: string;    pointedProfileId: string;    pointedPubId: string;    referrerProfileIds: string[];    referrerPubIds: string[];    // will be empty array if not action modules set    actionModules: string[];    // will be empty array if not action modules set    actionModulesInitDatas: string[];    // will null if not set    referenceModule: string | null;    // will be null if not set    referenceModuleData: string | null;    // will be null if not set    referenceModuleInitData: string | null;  };  pubId: string;  // will be empty array if not action modules set  actionModulesInitReturnDatas: string[];  // will null if not set  referenceModuleInitReturnData: string | null;  // will null if not set  referenceModuleReturnData: string | null;  transactionExecutor: string;  timestamp: number;  // will not be defined if its a momoka quote  logIndex?: number;  txHash?: string;  txIndex?: number;}

METADATA_PUBLICATION_COMPLETE

A notification is emitted when the publication metadata has been snapshotted and indexed by the API.

For the exact metadata type definition, refer to the @lens-protocol/metadata package.

import { PublicationMetadata } from "@lens-protocol/metadata";import { PublicationMetadata as LegacyPublicationMetadata } from "@lens-protocol/metadata/legacy";
interface Response {  profileId: string;  pubId: string;  // pub id are counters of the publication so they clash with profiles  // on the server we build up our own publication id to allow it to be searchable  // this is {profileId}-{pubId} and is used in all our API calls and responses  // this is the mirror publication id  serverPubId: string;  // the metadata extracted for you  metadata: PublicationMetadata | LegacyPublicationMetadata;  // the snapshot url for fast fetching  snapshotLocation: string;}

METADATA_PUBLICATION_FAILED

A notification is emitted when the snapshotting of the publication metadata fails. This could occur if the metadata is invalid or unreachable. The snapshot process will retry periodically for 20 minutes before marking it as failed. However, if the metadata is invalid, it won't retry and will immediately mark it as failed, providing an error reason.

interface Response {  profileId: string;  pubId: string;  // pub id are counters of the publication so they clash with profiles  // on the server we build up our own publication id to allow it to be searchable  // this is {profileId}-{pubId} and is used in all our API calls and responses  // this is the mirror publication id  serverPubId: string;  // the reason why it failed  errorReason: string;  // if it was unreachable for 20 minutes  timeoutRequest: boolean;}

PROFILE_MENTIONED

This event is emitted when a profile is mentioned in a publication. It serves to notify the mentioned profile about the reference in the publication.

Type
interface Response {  profileIdPointed: string;  pubIdPointed: string;  // pub id are counters of the publication, so they clash with profiles  // on the server, we build up our publication id to allow it to be searchable  // this is {profileId}-{pubId} and is used in all our API calls and responses  // this will be the publication the mention was created on  serverPubIdPointer: string;  handle: string;  profileId: string;  content: string;  contentURI: string;  snapshotLocation: string;  timestamp: Date;}

PUBLICATION_ACTED

This emits when a profile acted on a publication.

Type
interface Response {  publicationActionParams: {    publicationActedProfileId: string;    publicationActedId: string;    actorProfileId: string;    referrerProfileIds: string[];    referrerPubIds: string[];    actionModuleAddress: string;    actionModuleData: string;  };  actionModuleReturnData: string;  transactionExecutor: string;  timestamp: number;  logIndex: number;  txHash: string;  txIndex: number;}

PUBLICATION_COLLECTED

This event is emitted when a publication is collected.

Type
interface Response {  // pub id are counters of the publication so they clash with profiles  // on the server we build up our own publication id to allow it to be searchable  // this is {profileId}-{pubId} and is used in all our API calls and responses  serverPubId: string;  collectedProfileId: string;  collectedPubId: string;  collectorProfileId: string;  nftRecipient: string;  collectActionData: string;  collectActionResult: string;  collectNFT: string;  tokenId: string;  collectNFT: string;  collectNFT: string;  transactionExecutor: string;  timestamp: number;  logIndex: number;  txHash: string;  txIndex: number;}

PUBLICATION_REACTION_ADDED

This event is emitted when a profile adds a reaction to a publication.

Please note that reactions function as a toggle. For instance, if a profile upvotes a publication and then downvotes it, the initial upvote is invalidated. A profile is only allowed to have one active reaction on a publication at a time.

Type
interface Response {  profileId: string;  // pub id are counters of the publication so they clash with profiles  // on the server we build up our own publication id to allow it to be searchable  // this is {profileId}-{pubId} and is used in all our API calls and responses  serverPubId: string;  type: string;  // unix timestamp  reactedAt: number;}

PUBLICATION_REACTION_REMOVED

This event is emitted when a profile removes a reaction from a publication.

Type
interface Response {  profileId: string;  // pub id are counters of the publication so they clash with profiles  // on the server we build up our own publication id to allow it to be searchable  // this is {profileId}-{pubId} and is used in all our API calls and responses  serverPubId: string;  type: string;}

PUBLICATION_HIDDEN

This event is emitted when a profile hides a publication. Please note that while the content and media of the publication are hidden, the API still returns these publications to maintain thread integrity. However, these hidden publications do not appear in timelines, search results, profiles, or explore queries.

Type
interface Response {  profileId: string;  // pub id are counters of the publication so they clash with profiles  // on the server we build up our own publication id to allow it to be searchable  // this is {profileId}-{pubId} and is used in all our API calls and responses  serverPubId: string;}

PUBLICATION_REPORTED

This event is emitted when a publication is reported.

Type
interface Response {  // pub id are counters of the publication so they clash with profiles  // on the server we build up our own publication id to allow it to be searchable  // this is {profileId}-{pubId} and is used in all our API calls and responses  serverPubId: string;  profileId: string;  reason: string;  subreason: string;  additionalComments: string | null;}

COLLECT_NFT_TRANSFERRED

This event is emitted when the collect NFT is transferred to a new owner. Please note that this event is also emitted when the NFT is minted.

Type
interface Response {  profileId: string;  pubId: string;  // pub id are counters of the publication so they clash with profiles  // on the server we build up our own publication id to allow it to be searchable  // this is {profileId}-{pubId} and is used in all our API calls and responses  serverPubId: string;  // each collect NFT minted has a token id the first one is 1 then 2 just like a normal NFT project  collectNFTId: string;  from: string;  to: string;  timestamp: number;  logIndex: number;  txHash: string;  txIndex: number;}

Protocol Events

COLLECT_MODULE_REGISTERED

This event is emitted when a Collect Action Module is registered.

interface Response {  collectModule: string;  collectModuleName: string;  allowlisted: boolean;  timestamp: number;  logIndex: number;  txHash: string;  txIndex: number;}

INDEXER_MODULE_GLOBALS_TREASURY_FEE_SET

This event is emitted when the global treasury fee for the module is set.

interface Response {  prevTreasuryFee: string;  newTreasuryFee: string;  timestamp: number;  logIndex: number;  txHash: string;  txIndex: number;}

COLLECT_NFT_DEPLOYED

This event is emitted when the collect NFT is deployed. Keep in mind that Collect NFTs are lazy-loaded, meaning they are only deployed when the first collect occurs.

interface Response {  profileId: string;  pubId: string;  // pub id are counters of the publication so they clash with profiles  // on the server we build up our own publication id to allow it to be searchable  // this is {profileId}-{pubId} and is used in all our API calls and responses  serverPubId: string;  collectNFT: string;  timestamp: number;  logIndex: number;  txHash: string;  txIndex: number;}

COLLECT_OPEN_ACTION_MODULE_ALLOWLISTED

This event is emitted when an Open Action Module is either added to or removed from the allowlist.

Type
interface Response {  moduleName: string;  collectModule: string;  whitelist: string;  timestamp: number;  logIndex: number;  txHash: string;  txIndex: number;}

CURRENCY_MODULE_ALLOWLISTED

This event is emitted when a currency module is either added to or removed from the allowlist.

interface Response {  currency: string;  name: string;  symbol: string;  decimals: number;  prevWhitelisted: boolean;  whitelisted: boolean;  timestamp: number;  logIndex: number;  txHash: string;  txIndex: number;}

FOLLOW_MODULE_ALLOWLISTED

This event is emitted when a Follow Module is allowlisted or removed from the allowlist.

interface Response {  followModule: string;  whitelisted: boolean;  timestamp: number;  logIndex: number;  txHash: string;  txIndex: number;}

FOLLOW_MODULE_SET

This event is emitted when a profile modifies their Follow Module.

interface Response {  profileId: string;  followModule: string;  followModuleReturnData: string;  timestamp: number;  logIndex: number;  txHash: string;  txIndex: number;}

REFERENCE_MODULE_ALLOWLISTED

This event is emitted when a Reference Module is allowlisted or removed from the allowlist.

interface Response {  referenceModule: string;  referenceModuleName: string;  whitelisted: boolean;  timestamp: number;  logIndex: number;  txHash: string;  txIndex: number;}

OPEN_ACTION_MODULE_ALLOWLISTED

This event is emitted when a new Open Action Module is allowlisted or removed from the allowlist.

Type
interface Response {  actionModule: string;  openActionModuleName: string;  id: string;  whitelisted: boolean;  timestamp: number;  logIndex: number;  txHash: string;  txIndex: number;}

PROTOCOL_LENS_HUB_ADDRESS_SIG_NONCE_UPDATED

This event is emitted when the signature nonce of a Lens Hub address is updated.

Type
interface Response {  signer: string;  nonce: string;  timestamp: number;  logIndex: number;  txHash: string;  txIndex: number;}

PROTOCOL_TOKEN_HANDLE_ADDRESS_SIG_NONCE_UPDATED

This event is emitted when the signature nonce of a token handle address is updated.

Type
interface Response {  signer: string;  nonce: string;  timestamp: number;  logIndex: number;  txHash: string;  txIndex: number;}

PROTOCOL_STATE_CHANGED

This event is emitted when there's a change in the state of the protocol. The possible states are:

  • 0: Unpaused

  • 1: Publishing Paused

  • 2: Paused

interface Response {  caller: string;  prevState: number;  newState: number;  logIndex: number;  txHash: string;  txIndex: number;}

Media Events

MEDIA_SNAPSHOTTED

This event is emitted when media is successfully snapshotted. This can occur when a publication containing media is posted, or when a profile updates their metadata. In the case of a publication, the source will be the PublicationId. For a profile update, the source will be the ProfileId.

interface Response {  originalUrl: string;  snapshottedUrl: string;  source: string;}

MEDIA_SNAPSHOT_FAILED

This event is emitted when the snapshotting of media fails. This can occur due to a timeout after all retry attempts, if the URL is invalid, or if the content is unavailable at the time (for example, due to a 404 error or unfinished IPFS pinning).

interface Response {  originalUrl: string;  source: string;  message: string;}