Yeah! That’s true. Now we can send push notifications in a decentralized fashion using the public blockchain — Ethereum.

Push notifications are crucial in any applications for improving the user experience. People feel more engaged with the application and they prefer realtime information rather than delayed notifications through email or sms.

But the DeFi space is still new and emerging everyday, it demands some way to notify their users that has nothing to do with their personal data. The only identity of the user in the DeFi world is his/her wallet address.

And that’s what the EPNS (Ethereum Push Notification Service) does. It helps us to deliver push notifications to the users without the need for any personal information of the user. All we need to have is the wallet address of the user.

Let’s have a quick example of how the traditional push notification system works:

  • The user logs in to the mobile application using the credentials.
  • The unique device token associated with the user’s device is sent to the server.
  • The server sends push notifications to the device using Firebase or Apple Push Notification Sever using the device token of the user.

It is okay for a traditional application to implement this method. But it is not suitable for the DeFi apps to follow the same flow.

So let’s have a look at how EPNS works (in a nutshell).

  • DeFi application admin/owner/governor creates a channel for the app.
  • Users can subscribe to the channel using their wallet if they want to receive notifications on important events like liquidation of their position in a money market protocol, etc.,
  • The notification engine can watch events on the platform and send push notifications to the channel. It can either broadcast or send a targeted notification to a particular wallet address.
  • The user can receive the notification via the EPNS browser extension (or) EPNS Mobile Application.

As simple as that!

Let us build a simple NodeJS service for demo using. It is a simple news service which sends the latest news on cryptocurrency for every 30 minutes. Though it has nothing to do with DeFi it is sufficient to demonstate channel creation and broadcasting message to the subscribers of the channel.

Creating our News Channel:

We have 2 options:

  • Creating the channel using a NodeJS script
  • Creating the channel using the EPNS web interface.

For this demo, I’ll be creating the channel using EPNS web interface.

Please refer to this link which contains the NodeJS Script that can be used for creating a channel.

Let’s open up their staging application — https://staging-app.epns.io

Connect your web3 wallet. I’ll use MetaMask for this demo. Once connected click on the Create Your Channel tab.

You can create a channel from the interface by uploading the channel icon, channel name, image and so on.,

For this demo, I have create a simple news channel with the following details

Note: You will need some DAI tokens to create a channel. You can get it from the Get Free DAI for Channel button or mint manually.

Once the channel has been created, you can see the channel name and description under the Channels tab.

Great! Now other users can subscribe to this channel to receive the notifications.

Sending Notifications:

We can send notifications programmatically as well as through the interface. If we need to send important news of our platform, then we can use interface to send. But if we want to automate it based on some events, then the notifications can be sent programmatically.

Here’s a simple script to send the news data to all the subscribers (broadcasting)

require("dotenv").config();
const Ipfs = require("nano-ipfs-store"); // Used to spin up local ipfs node
const  ethers  = require("ethers");
const epnsAbi = require("../abis/epnsAbi.json");
const { EPNS_PROXY_ADDRESS, PROVIDER } = require("../constants");

async function newMessage(newsTitle, description) {
  return await new Promise((resolve, reject) => {
    const title = newsTitle;
    const message = description;
    const payloadTitle = newsTitle;
    const payloadMsg = description;

    const payload = {
      notification: {
        title: title,
        body: message,
      },
      data: {
        type: "1", // Group Message
        secret: "",
        asub: payloadTitle,
        amsg: payloadMsg,
        acta: "https://medium.com",
        aimg: "",
      },
    };

    resolve(payload);
  });
}

async function sendMessage(title, description) {
  return new Promise((resolve, reject) => {
    let EPNS_CONTRACT_ABI = epnsAbi;
    let EPNS_CONTRACT_ADDR = EPNS_PROXY_ADDRESS;
    let channelPK = process.env.PRIVATE_KEY;

    //Initialize the EPNS Contract
    const contract = new ethers.Contract(
      EPNS_CONTRACT_ADDR,
      EPNS_CONTRACT_ABI,
      PROVIDER // Ropsten Provider
    );
    const wallet = new ethers.Wallet(channelPK, PROVIDER);
    contractWithSigner = contract.connect(wallet); //Connect the signer

    newMessage(title, description).then((payload) => {
      const jsonizedPayload = JSON.stringify(payload);
      const ipfs = Ipfs.at("https://ipfs.infura.io:5001");

      // Upload the IPFS payload
      ipfs.add(jsonizedPayload).then((ipfshash) => {
        const notificationType = parseInt(payload.data.type);
        const identity = notificationType + "+" + ipfshash;
        const identityBytes = ethers.utils.toUtf8Bytes(identity);
        const channelAddress = "YOUR_CHANNEL_ADDR";

        //Send the notification
        const txPromise = contractWithSigner.sendNotification(
          channelAddress,
          identityBytes
        );

        txPromise
          .then(async function (tx) {
            console.log("News update sent", tx.hash);
            resolve(tx);
          })
          .catch((err) => {
            console.log("failed");
            reject("Unable to complete transaction, error: %o", err);
          });
      });
    });
  });
}
module.exports = { sendMessage };

You can see the sendMessage method receives the title and description of the news and broadcasts it using the sendNotification method of the EPNS smart contract.

Here’s how the news service invokes the sendMessage function every 30 minutes.

const axios = require("axios");
const { sendMessage } = require("./utils/send");

const NEWS_API =
  "https://newsdata.io/api/1/news?apikey=<YOUR_KEY>&q=cryptocurrency&language=en";

 
setInterval(async () => {
  let resp = await axios.get(NEWS_API);
  
  if (resp.status != 200) return;
  
  let notificationTitle = "News update - " + new Date().toUTCString();
  
  let notificationPayload = resp.data.results[0].title;
    
  await sendMessage(notificationTitle, notificationPayload);
  
}, 30 * 60 * 1000); //30 Minutes

 

You can use the staging EPNS chrome extension to receive the notifications. There are also mobile applications for EPNS on android and iOS, but they are only for the channels created and listed on app.epns.io. For testing purposes, we can use their browser extensions to receive notifications.

We need to first add our wallet address to receive the notifications.

Once the wallet address is added, then you can receive the notifications from the subscribed channels

EPNS is still in the development stage and not production ready for every applications to create channels. The EPNS team is working with some well-known protocols like AAVE, PoolTogether to integrate push notifications. Hope it will be out soon for all the users. Meanwhile we can play around with the alpha staging app.

Happy Coding!

Author

Backend Engineer and Blockchain Developer. Keep learning | Spread Knowledge

Write A Comment