EPNS makes it extremely easy to open and maintain a genuine channel of communication with between any dApps (referred to as channels) and their users (referred to as subscribers).
It's designed to be minimal on setup but maximally powerful in every aspect of messaging from the type of messages it can deliver (groups, secrets and targeted) to the way and context by which those messages are shown (call to action, encrypted url's, images, updates, events and more).
As is in the name, Ethereum Push Notification Service aims to connect decentralized ecosystem to centralized ecosystem and wants to ensure that the intended user of a service, dApp, dEx, deFi or even a smart contract can utilize EPNS to reach and form a genuine communication channel with their users without ever needing to compromise on the decentralize aspect of the blockchain.
To make such a service, we knew from the start that we can't contain it to a single channel as that restricts the flow of information. This also meant that the service will going to be ever evolving as the needs and features of blockchain evolve.
Moving along to the juicier details... EPNS is composed of:
- Mobile App
- Push Server and Services
- Smart Contract (and IPFS storage)
Each of which has a particular role in ensuring that the entire service works. Let's have an in depth look at what they do below.
Mobile App: This forms the heart of EPNS when it comes to interacting with and delivering messages from different dApps to their intended users. As such, special care is given to each aspect and feature present in the mobile app. The app is designed to be extremely simple to setup and for the most part hides all the security and intrinsic details that happen in the background which enables the user to receive the notifications and decrypt / transform them to the intended message type. It's as important to deliver the message to the user as it is to ensure that the message is never ever delivered to someone else. To ensure this, the app takes a number of initiative including asking and storing the encrypted private key without ever having a way to recover it if the user forgets the passcode (Hashing and AES). The app and in fact the whole ecosystem also uses public-private key encryption based on ECIES to ensure that messages traveling in and around blockchain or in between transport is always safe. While safety is really important for us as it increases the user's faith in us and thereby adoption, it's not the only thing which went inside the app.
The mobile app is a tool which is always there with the user and thus need to be also usable and feature rich in delivering notifications (so as to not to go to the waste bin). This meant that we took extreme care and focus in developing the aspects of the app, the way it will present the notifications to the users and how it can give access to features beneficial to the user (like archive / unarchive). There are several features in the mobile app which have been thought and rethought before they were added, for example: utilizing the notification rich format to always ensure that the channel (dApp) sending notification is always clear to the user. The feed on which the notification is presented is also feature filled with call to action, cover images and even rich text formatting to ensure information delivery in the most intricate way. All this of course doesn't take away from our focus on the feature that forms the core of EPNS - connecting user wallet and their device tokens and using that information to deliver notifications to them on all their chosen product. We are proud to say that due to the extreme focus on the layout, message delivery and security. The app is considered by us to be a beta launch ready product :).
Push Server and services: The push server is actually a amalgamation of different services action together to inch delivery and connection of decentralized and centralized ecosystem. The server is responsible for the following things:
1. Authenticating user without central services or security details: We did this by creating a tweaked version of request-challenge-reply process. Whenever a device token is generated on the app of the user, the app needs to communicate that to the server and the server then stores that anonymous token along with mapping of your wallet to finally dispatch notification to you. There are three issues with this: 1) ensuring that the device token sent by the user belongs to the wallet they own (disabling spoofing attack). 2) A user is not able to mass spam and register random tokens or remap their wallet to someone else device tokens and 3) The user should not in under any circumstances send their private key or centralized credentials to authorize for the service. To handle all 3 issues, we turned to cryptography and this is what we came up with (and is happening on the server right now) -> User requests the server for a slot id and sends the public key of their wallet to the server -> The server generates a random password and a slot id for the user, it then stores the password on the server with the slot id for next 10 mins and sends the user the encrypted version of this password back with the plain slot id -> The user then needs to decrypt the password using their private key of the public key they sent earlier (which they can only do if they have both) and then using the plain obtained password as seed needs to AES encrypt the device token, some other data and a register operation code -> they then have to send these encrypted details back to the server with the slot id -> The server now checks if the slot id is valid, if so retrieves the password stored with it and unlocks the op code first with it, if the op code matches than the user is genuine and the device token is decrypted and stored.
I think I am digressing from the point here so will try to summarize. In essence the entire suite of EPNS talks with each others and takes baby steps towards becoming compatible with each other. The mobile app is responsible for handing users and sending / registering tokens. The server is responsible for listening to the smart contract, fetching the channel, subscribers info from the events emitted and the state change. It is also responsible to store tokens for all the users who are on table or mobile. It also listens to web3 endpoints and connect these to successfully form a compatible payload which the app detects.
The smart contract on the other hand introduces DeFi based interest earning from the fees collected by the smart contract when someone forms a channel. this fees goes into aave pool which gives us interest generating aDai that is acts as a further incentive for the user.
How It's Made
Push Notifications are hard... and the project uses various tools and technologies to make sure that everything remain interoperable with each other. During the entire stint, I think I have worked on reactjs, react native, solidity, nodejs, typescript and a few dozen more tech and tools. This is the most fun I have had which learning and buidling at the same time :)