├── .gitbook └── assets │ ├── highlevel.jpg │ ├── inputdappserverless.png │ ├── inputserver.png │ └── inputsmartcontract.png ├── .gitignore ├── README.md ├── SUMMARY.md ├── activating-service-on-protocol.md ├── payload_structure ├── channel.json ├── channel_example.json ├── message.json └── message_example.json ├── sending-notifications ├── README.md ├── dapp-serverless-workflow.md ├── notification-payload-types.md ├── server-workflow.md └── smart-contract-workflow.md ├── tenets.md └── tenets └── README.md /.gitbook/assets/highlevel.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pushchain/push-docs-outdated/e8899254d9a683df0f2f07d1e169d38cce78d3f7/.gitbook/assets/highlevel.jpg -------------------------------------------------------------------------------- /.gitbook/assets/inputdappserverless.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pushchain/push-docs-outdated/e8899254d9a683df0f2f07d1e169d38cce78d3f7/.gitbook/assets/inputdappserverless.png -------------------------------------------------------------------------------- /.gitbook/assets/inputserver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pushchain/push-docs-outdated/e8899254d9a683df0f2f07d1e169d38cce78d3f7/.gitbook/assets/inputserver.png -------------------------------------------------------------------------------- /.gitbook/assets/inputsmartcontract.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pushchain/push-docs-outdated/e8899254d9a683df0f2f07d1e169d38cce78d3f7/.gitbook/assets/inputsmartcontract.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # General 2 | .DS_Store 3 | .AppleDouble 4 | .LSOverride 5 | 6 | # Icon must end with two \r 7 | Icon 8 | 9 | 10 | # Thumbnails 11 | ._* 12 | 13 | # Files that might appear in the root of a volume 14 | .DocumentRevisions-V100 15 | .fseventsd 16 | .Spotlight-V100 17 | .TemporaryItems 18 | .Trashes 19 | .VolumeIcon.icns 20 | .com.apple.timemachine.donotpresent 21 | 22 | # Directories potentially created on remote AFP share 23 | .AppleDB 24 | .AppleDesktop 25 | Network Trash Folder 26 | Temporary Items 27 | .apdisk 28 | 29 | # Windows thumbnail cache files 30 | Thumbs.db 31 | Thumbs.db:encryptable 32 | ehthumbs.db 33 | ehthumbs_vista.db 34 | 35 | # Dump file 36 | *.stackdump 37 | 38 | # Folder config file 39 | [Dd]esktop.ini 40 | 41 | # Recycle Bin used on file shares 42 | $RECYCLE.BIN/ 43 | 44 | # Windows Installer files 45 | *.cab 46 | *.msi 47 | *.msix 48 | *.msm 49 | *.msp 50 | 51 | # Windows shortcuts 52 | *.lnk 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: This page is outdated and in development 3 | --- 4 | 5 | # Ethereum Push Notification Service 6 | 7 | {% hint style="danger" %} 8 | This page is outdated and in development 9 | {% endhint %} 10 | 11 | ## EPNS \(Ethereum Push Notification Service\) 12 | 13 | The EPNS protocol is the first of its kind decentralized defi notification protocol which enables users \(wallet addresses\) to receive notifications. 14 | 15 | Using the protocol, any dApp, service or smart contract can send notifications to users\(wallet addresses\) in a platform agnostic way \(mobile, tablet, web, fav. wallets, etc\). _**The DeFi aspect of the protocol also ensures that the user receives and earns from those notifications.**_ 16 | 17 | Slides: [https://docs.google.com/presentation/d/1hweNz4QSDLdCVWKa3T8lw-ZwmhhDuPnhim-bgeUsIks/edit\#slide=id.g85c3ec45e5\_1\_38](https://docs.google.com/presentation/d/1hweNz4QSDLdCVWKa3T8lw-ZwmhhDuPnhim-bgeUsIks/edit#slide=id.g85c3ec45e5_1_38) 18 | 19 | Teaser: [https://www.youtube.com/watch?v=kwwnlmUpRsk](https://www.youtube.com/watch?v=kwwnlmUpRsk) 20 | 21 | Live Demo: [https://www.youtube.com/watch?v=uI-YhyUyMgw](https://www.youtube.com/watch?v=uI-YhyUyMgw) 22 | 23 | ## What are the benefits of having EPNS? 24 | 25 | Idea behind EPNS is to expand on and integrate existing ways by which a user can be reached out to by different dApp owners, smart contracts, etc. The EPNS service can be used in a variety of ways: 26 | 27 | * It can be used to relay important loan liquidation, funds running out, debt positions notifies to a specific user in \#DeFi 28 | * It can be used to inform users of important upcoming events, notifications, etc of specific dApps \(via App Owners\) 29 | * It can be further enhanced to convey push notifications that act as security mechanisms \(for example: a Trusted App Owner group is subscribed by all exchanges, the addresses relayed by this app owner in specific format can automatically blacklist those addresses out\) 30 | * It can potentially be used by Ethereum itself for major announcements like launching of Ethereum 2.0, notifications to miners for any upcoming fork, etc 31 | * It can potentially replace the way new projects gather user's sensitive information. For Example, when an ICO is conducted or a new cryptocurrency is launched, instead of these projects relying on emails to store and communicate about their updates, they can instead offer EPNS service which is anonymized and doesn't have a central point of failure. 32 | 33 | ## Technical Details 34 | 35 | Following definitions are used in the rest of the spec to refer to a particular category or demography of the users of the protocol. 36 | 37 | ### Definitions 38 | 39 | | Term | Description | 40 | | :--- | :--- | 41 | | Contract Owner | The owner of the contract, specifically the address by which the contract is deployed | 42 | | App Owner | The third party projects, dApps or smart contract, specifically the address which forms their identity as well as the custom opt-in group which the subscribed users will recieve message from | 43 | | Users | All the users who don't fall in either of the above category | 44 | | App Owner Group | The group which contains subscribed users of a particular App Owner | 45 | | Subscribed Users | The users who have subscribed to a specific App Owner Group | 46 | 47 | For the purpose of explaining above EPNS terms, let's take the example of Youtube and the various associated roles. 48 | 49 | | Term | Description | 50 | | :--- | :--- | 51 | | Youtube | Contract Owner | 52 | | Channels | App Owner Groups | 53 | | Channel Owners | App Owners | 54 | | Users | Users | 55 | | Subscribed Users | Users subscribed to a specific App owner group | 56 | 57 | ### Game Theory 58 | 59 | Inorder to ensure the proper participation of all players, following game theory is proposed, features marked with indentation will mostly be excluded from MVP: 60 | 61 | * The **contract owner** doesn't have any ability to send message on behalf of **app owners** 62 | * > The **app owners** might spoof other trusted apps and thus will have to be verified or a spam system developed so that users can mark them as spoof or a similar mechanism 63 | * The **app owners** need explicit permission from the **users** before messages can be sent to them 64 | * The **app owners** need to stake some minimum DAI to ensure spam free environment, this is going to be minimal but good enough to ascertain good behavior \(for example: 50 DAI\) 65 | * The **users** need to transact on blockchain to specifically subscribe or unsubscribe to an **app owner group**, this leads to an incentive issue, ie: why would a user spend gas in most cases? 66 | * To counter this, The staked DAI from **app owners** can in turn be used as a incentive for **users** to subscribe to the specific **app owner** group 67 | * This can be done by using service like [**AAVE**](https://app.aave.com/deposit/DAI) to accure interest on the said DAI and distribute it to the subscribed **users** group 68 | * This incentivizes the **users** to spend gas to perform transaction operation of subscribe 69 | * The **app owners** can stake more DAI if they want to, since the **users** are incentivized to subscribe 70 | * > The **app owner** can blacklist a certain **user** from their group if they want to 71 | * The **app owners** can reclaim this DAI back, reclaiming this DAI will also destroy the **app owner group**, a fees of 10 DAI will also be held back for the **contract owner**, the fees is small enough for serious players to not worry about but will act as a further deterrent for bad players 72 | 73 | ### Features 74 | 75 | EPNS should be able to: 76 | 77 | * Provide function for dApp or Smart Contract to register itself as **app owner** 78 | * The **app owner** needs to upload their profile in a json format to IPFS, this will contain their name and icon at the beginning, this json file hash is stored on-chain and fetched and shown along with the message they send 79 | * The **users** can subscribe to multiple **app owner group** through their own action 80 | * The **subscribed users** can unsubscribe from an **app owner group** through their own action 81 | * The **app owner** can send messages to their **subscribed users** 82 | * The messages sent from **app owner** can also indicate if they want to use push notification service of [epns.io](https://epns.io). 83 | * A small fee will be charged for using the service for push notification 84 | * To ensure that push notification service usage is done after paying the fee, the message will be emitted with a flag 85 | * The **app owner** can send unencrypted message to their **app owner group** in which case the message will reach every **subscribed users** 86 | * The **app owner** can also send encrypted message to specific **subscribed user** in which case the message will be encrypted with the specific user's public key 87 | * In the encrypted message scenario, the user private key will be used to decrypt the message, this means that the mobile app needs to store the private key of the user wallet which will be done in a safe and secure way. The private key in any case will never leave the user's device 88 | * The web3 provider can also use a similar mechanism to display notifications to the users in the future 89 | * The **app owner** message is to be stored in the JSON file on [ipfs](https://ipfs.io/) and the hash of that will be mapped. this will be interpreted by the server handling push notifications and also by any web3 providers who wants to use the service 90 | * > The JSON file will carry msg type ids which can ensure that the system can be extended beyond the ecosystem, ie: for having a trusted **app owner** with exchanges and **subscribed users** that can monitor and lock down blacklisted wallets automatically in the future. 91 | 92 | ### Proposed Structure 93 | 94 | **Proposed App Owner JSON File Format** 95 | 96 | | Name | Type | Description | 97 | | :--- | :--- | :--- | 98 | | name | _string_ | The name of the app to be displayed | 99 | | icon | _base64_ | 128x128 icon to be associated with the app | 100 | 101 | **Proposed message JSON File Format** 102 | 103 | | Name | Type | Description | 104 | | :--- | :--- | :--- | 105 | | type | _Integer_ | The message type, currently will be 1 indicating normal message | 106 | | payload | _json_ | The Payload of the message | 107 | 108 | **Payload Type 1 - Normal Push Notification** 109 | 110 | | Name | Type | Description | 111 | | :--- | :--- | :--- | 112 | | title | _String_ | The title of the message | 113 | | message | _String_ | The message | 114 | | cta | _String \(Url\) \(Optional\)_ | The link to perform call to action if any | 115 | | image | _String \(Url\) \(Optional\)_ | To make the notification rich | 116 | | encrypted | _Bool_ | message is encrpted or not | 117 | 118 | **Note:** The push notification icon will be taken from the App Owner Json Icon and will be displayed on the right side of the notification area for mobile. 119 | 120 | ### Tech Spec 121 | 122 | EPNS system needs to deal with the following to allow **specific, user permissioned messaging from different custom opt-in groups created by app owners**: 123 | 124 | * Creation of App Owners \(dApp Owners, Smart Contracts, etc that want to send message\) 125 | * Storage of Message 126 | * User Subscription to Groups 127 | * Broadcasting of Message 128 | 129 | -- Via EPNS Push Notification Mobile App 130 | 131 | -- Via Web3 Provider 132 | 133 | ### TBA 134 | 135 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Table of contents 2 | 3 | * [\[Outdated Page\]](README.md) 4 | * [Activating Service on Protocol](activating-service-on-protocol.md) 5 | * [Sending Notifications](sending-notifications/README.md) 6 | * [Notification Payload Types](sending-notifications/notification-payload-types.md) 7 | * [From dApp / Serverless](sending-notifications/dapp-serverless-workflow.md) 8 | * [From Server](sending-notifications/server-workflow.md) 9 | * [From Smart Contract](sending-notifications/smart-contract-workflow.md) 10 | * [Tenets](tenets.md) 11 | 12 | -------------------------------------------------------------------------------- /activating-service-on-protocol.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Coming soon 3 | --- 4 | 5 | # Activating Service on Protocol 6 | 7 | 8 | 9 | {% hint style="info" %} 10 | Sending notification from your service requires **a one time process** of staking fees for creating a channel. Creating channel is extremely simple and can be done via [our dApp](https://app.epns.io) or can be automated on server or smart contract. 11 | {% endhint %} 12 | 13 | -------------------------------------------------------------------------------- /payload_structure/channel.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Your Channel name (Limit: 40 Chars)", 3 | "info": "Short Description of your channel (Limit: 240 Chars)", 4 | "url": "Your Channel's website (Limit: 160 Chars)", 5 | "icon": "Base64 encoded image (Limit 128x128) else server will reject" 6 | } 7 | -------------------------------------------------------------------------------- /payload_structure/channel_example.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ENS (Ethereum Name Service)", 3 | "info": "ENS offers a secure & decentralised way to address resources both on and off the blockchain using simple, human-readable names.", 4 | "url": "https://ens.domains/", 5 | "icon": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAIAAABMXPacAAAACXBIWXMAAAsTAAALEwEAmpwYAAAGvmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDAgNzkuMTYwNDUxLCAyMDE3LzA1LzA2LTAxOjA4OjIxICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgKE1hY2ludG9zaCkiIHhtcDpDcmVhdGVEYXRlPSIyMDIwLTA1LTEzVDE2OjM5OjMyKzA1OjMwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAyMC0wNS0xNlQxMToxNzoyNyswNTozMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAyMC0wNS0xNlQxMToxNzoyNyswNTozMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo2NDU3OTU0OC1hMjdjLTQ0N2ItYjFhMi1iZjYyYjg2ZDYwMjYiIHhtcE1NOkRvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDoxMjk2ZDhkZi02OWNjLWJmNGQtOGEzNy1hNjU0MDk0N2RmOWEiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo5NGIxNmJhYy04NzAxLTQ3ZjAtOGExZi1kYjlkN2JkMzAwMmYiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjk0YjE2YmFjLTg3MDEtNDdmMC04YTFmLWRiOWQ3YmQzMDAyZiIgc3RFdnQ6d2hlbj0iMjAyMC0wNS0xM1QxNjozOTozMiswNTozMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDpkOGJhZGNmNi02YzRiLTQ2YzgtYjhjYi05YjUwMDMwYzNmYzMiIHN0RXZ0OndoZW49IjIwMjAtMDUtMTZUMTE6MTc6MTIrMDU6MzAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAoTWFjaW50b3NoKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6NjQ1Nzk1NDgtYTI3Yy00NDdiLWIxYTItYmY2MmI4NmQ2MDI2IiBzdEV2dDp3aGVuPSIyMDIwLTA1LTE2VDExOjE3OjI3KzA1OjMwIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgKE1hY2ludG9zaCkiIHN0RXZ0OmNoYW5nZWQ9Ii8iLz4gPC9yZGY6U2VxPiA8L3htcE1NOkhpc3Rvcnk+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+da2UygAAGzVJREFU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" 6 | } 7 | -------------------------------------------------------------------------------- /payload_structure/message.json: -------------------------------------------------------------------------------- 1 | { 2 | "notification": { 3 | "title": "The title of your message displayed on screen (50 Chars)", 4 | "body": "The intended message displayed on screen (180 Chars)" 5 | }, 6 | "data": { 7 | "type": "1 or 2 or any other message type later invented... 1 is group message and 2 is secret message (1 or 2)", 8 | "secret": "[Empty unless type is 2] The encrypted secret (No more than 15 Chars)" 9 | "asub": "[Empty for Optional] The subject of the message displayed inside app (80 Chars)", 10 | "amsg": "The intended message displayed inside app (500 Chars)", 11 | "acta": "[Empty for Optional] The cta link parsed inside the app", 12 | "aimg": "[Empty for Optional] The image url which is shown inside the app" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /payload_structure/message_example.json: -------------------------------------------------------------------------------- 1 | { 2 | "notification": { 3 | "title": "Your trade order [BTC-ETH] is filled!", 4 | "body": "The intended message displayed on screen (150 Chars)" 5 | }, 6 | "data": { 7 | "type": "1", 8 | "secret": "[Empty unless type is 2] The encrypted secret (No more than 15 Chars)" 9 | "asub": "Your trade order [BTC-ETH] was executed at 7:00 AM for 100 ETH", 10 | "amsg": "[d:Channels] represent your favorite [b:dApps] or [b:Smart Contracts]. You will often get notifications from different channels.\n\nThe [b:top section] of the message contains information about these channels.\n\n[b:Clicking on it] takes you to their [b:website].", 11 | "acta": "https://uniswap.exchange", 12 | "aimg": "https://aintviral.com/wp-content/uploads/2018/09/The-Haines-Shoe-House-Pennsylvania-IMG-1-TESTO-1-1024x712.jpg" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /sending-notifications/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | Describes how notifications can be sent out by a dApp, service or a smart 4 | contract by interacting with our protocol. 5 | --- 6 | 7 | # Sending Notifications 8 | 9 | ## High Level Application Flow 10 | 11 | EPNS uses the following application flow to ensure storage, broadcasting and sending notifications. 12 | 13 | ![High Level Application Flow](../.gitbook/assets/highlevel.jpg) 14 | 15 | {% hint style="info" %} 16 | Abstracting the data layer on chain \(directly or indirectly\) ensures notifications are platform agnostic. 17 | {% endhint %} 18 | 19 | {% hint style="success" %} 20 | In the future, we might even support other centralized services apart from Mobile, Tablet, Chrome, Firefox, favorite user wallets, etc. 21 | 22 | As a service, these are automatically enabled for you as and when we integrate them. 23 | {% endhint %} 24 | 25 | -------------------------------------------------------------------------------- /sending-notifications/dapp-serverless-workflow.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Workflow for sending notification via third party dApps / serverless model 3 | --- 4 | 5 | # From dApp / Serverless 6 | 7 | ## dApp / Serverless integration workflow 8 | 9 | EPNS allows various ways to integrate the protocol into your service. The following flow shows how a dApp can send notification to the protocol. 10 | 11 | ![Ethereum Push Notification Service \| dApp integration with protocol](../.gitbook/assets/inputdappserverless.png) 12 | 13 | ### Sending notification via the dApp 14 | 15 | 1. Use your internal logic to figure out what notification you want to send \(ie: alerting users on some smart contract event, some action of theirs, movement in their wallets, a podcast or post from your end, etc\). 16 | 2. Form the JSON payload using our JS Library or your which you want to send as notification. Please check [Notification Payload Types](notification-payload-types.md) for supported payload types and their requirements. 17 | 3. Interact with protocol using our JS Library or your own. 18 | 4. That's it, sit back and relax, we will take it on from here. 19 | 20 | -------------------------------------------------------------------------------- /sending-notifications/notification-payload-types.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | Explains the supported notification payload types and the payload data they 4 | carry. 5 | --- 6 | 7 | # Notification Payload Types 8 | 9 | ## Payload Description 10 | 11 | Ethereum Push Notification Service supports a variety of payload types and the list is ever expanding. 12 | 13 | {% hint style="info" %} 14 | The JSON Payload can differ with payload types ensuring flexibility of the content, data, storage interpretation and delivery. 15 | {% endhint %} 16 | 17 | {% hint style="info" %} 18 | Recommended to interface with **EPNS JS Library** for dApp / Serverless / Server flow to abstract the logic required to create notification payload. 19 | {% endhint %} 20 | 21 | | Payload Variable | Description | 22 | | :--- | :--- | 23 | | **notification** | \[Required\] Represents the notification typically delivered on the home screen of the platform \(mobile, tablet, web, etc\), the icon of the channel is automatically added to outline where the notification is coming from. | 24 | | title | \[Required\] The title of the message displayed on the screen, this differs from the **data json** because the title while transforming the payload can be different than the title presented. For example, secret notification title are always transformed to say **Channel has sent you a secret notification.** | 25 | | body | \[Required\] The body of the message displayed on the screen, this differs from the **data json** because the title while transforming the payload can be different than the title presented. For example, secret notification body are always transformed to say **Please open the dApp / app to view your notification.** | 26 | | **data** | \[Optional\] The data field present here forms the visual **feedBox** for the user. Indicates the data field the payload will carry. This allows the notification to transform according to the payload type and the content defined on the platform frontend \(ie: app, dApp, wallet, etc\). | 27 | | type | \[Required\] Each payload has a type which tells how the data should be interpreted, this type is mirrored on the protocol function call as well. | 28 | | secret | \[Optional\] is required for certain payload types to decrypt the data. | 29 | | asub | \[Optional\] is the subject shown in the feed item. | 30 | | amsg | \[Optional\] is the message shown in the feed item, has rich text formatting. | 31 | | acta | \[Optional\] is the call to action of that feed item. | 32 | | aimg | \[Optional\] is the image shown in the feed item, this field is also capable of carrying **youtube** links. | 33 | | atime | \[Optional\] time in epoch when the notification should be displayed, if present, the frontend should respect this field and delay the notification till the schedule is reached. If the time is before the current time, the notification is treated as to be dispatched and displayed immediately. | 34 | | **recipients** | \[Optional\] When present with appropriate payload type allows notification to delivered to many subscribers \(but not all subscriber\) of that channel. | 35 | 36 | {% hint style="info" %} 37 | If no **data** is carried in the **payload** \(or only **atime** is carried\), it is assumed that the notification is not important and hence **persist \(or appearance\)** in the **feedBox** of the user. 38 | {% endhint %} 39 | 40 | ## Payload Types 41 | 42 | ### Direct Protocol Payload \(Type 0\) 43 | 44 | Direct payload are special payloads meant for sending directly to protocol, the delimiter **+** divides the subject and message which are the only two fields it carries. 45 | 46 | ```text 47 | type+title+body 48 | ``` 49 | 50 | {% hint style="warning" %} 51 | It's always recommended to use other payloads for dApp or server interaction. This payload should be used sparingly when it's absolutely necessary. the type here is a special field which is different from the type in identity. 52 | {% endhint %} 53 | 54 | {% hint style="info" %} 55 | Always recommended to interface with **EPNS JS Library** for abstracting these details out. 56 | {% endhint %} 57 | 58 | ### Broadcast Payload \(Type 1\) 59 | 60 | Broadcast notification goes to all subscriber of a channel, the notification payload in this case is not encrypted. 61 | 62 | ```text 63 | { 64 | "notification": { 65 | "title": "The title of your message displayed on screen (50 Chars)", 66 | "body": "The intended message displayed on screen (180 Chars)" 67 | }, 68 | "data": { 69 | "type": "1", 70 | "secret": "", 71 | "asub": "[Optional] The subject of the message displayed inside app (80 Chars)", 72 | "amsg": "[Optional] The intended message displayed inside app (500 Chars)", 73 | "acta": "[Optional] The cta link parsed inside the app", 74 | "aimg": "[Optional] The image url or youtube url which is shown inside the app", 75 | "atime": "[Optional] Epoch time for the notification to be shown or dispatch" 76 | } 77 | } 78 | ``` 79 | 80 | ### Secret Payload \(Type 2\) 81 | 82 | Secret notifications are intended to be delivered to one subscriber of the channel, these are encrypted using ECIES\(Elliptic Curve Cryptography\) and AES\(Advanced Encryption Standard\). The secret which is generated by the channel using whatever means they prefer should be kept to 15 characters or less, this secret \(plain version\) uses AES to encrypt the fields: **asub, amsg, acta, aimg**. 83 | 84 | The rationale behind using ECIES with AES is to ensure that the payload is not over bloated. 85 | 86 | ```text 87 | { 88 | "notification": { 89 | "title": "The title of your message displayed on screen (50 Chars)", 90 | "body": "The intended message displayed on screen (180 Chars)" 91 | }, 92 | "data": { 93 | "type": "2", 94 | "secret": "No more than 15 characters, encrypted using public key of the intended recipient", 95 | "asub": "encrypted by secret using AES | [Optional] The subject of the message displayed inside app (80 Chars)", 96 | "amsg": "encrypted by secret using AES | [Optional] The intended message displayed inside app (500 Chars)", 97 | "acta": "encrypted by secret using AES | [Optional] The cta link parsed inside the app", 98 | "aimg": "encrypted by secret using AES | [Optional] The image url which is shown inside the app", 99 | "atime": "[Optional] Epoch time for the notification" 100 | } 101 | } 102 | ``` 103 | 104 | {% hint style="info" %} 105 | Why not just use ECIES? ECIES increases the length of the cipher text and hence the payload which will be delivered. Using ECIES with AES ensure the payload length is kept at a manageable level and allows channels to send more information in the notification while still keeping the best encryption practices. 106 | {% endhint %} 107 | 108 | #### Example Notification Payload \(Plain\) 109 | 110 | ```text 111 | { 112 | "notification": { 113 | "title": "The title of your message displayed on screen (50 Chars)", 114 | "body": "The intended message displayed on screen (180 Chars)" 115 | }, 116 | "data": { 117 | "type": "2", 118 | "secret": "vBGK71PFl7mzWob", 119 | "asub": "The Great Renewal: Your ENS Domain has expired and someone is about to get them", 120 | "amsg": "[d:ENS] domains from 2017 that have expired.\n\nGo check your [b:@ensdomains] right now and renew your accounts.", 121 | "acta": "https://ens.domains/", 122 | "aimg": "https://i.ibb.co/WKNVN9y/enssamplemsgimg.jpg", 123 | "atime": "1595083821" 124 | } 125 | } 126 | ``` 127 | 128 | {% hint style="info" %} 129 | **Recommended** to use the **EPNS** **JS Library** to handle the generation of encrypted payload easily, it can talk to our protocol to also fetch the public key required. 130 | {% endhint %} 131 | 132 | #### Example Notification Payload \(Encrypted\) 133 | 134 | ```text 135 | { 136 | "notification": { 137 | "title": "The title of your message displayed on screen (50 Chars)", 138 | "body": "The intended message displayed on screen (180 Chars)" 139 | }, 140 | "data": { 141 | "type": "2", 142 | "secret": "e291826a995ab03b0dd69c360f3deb3803e130dc7d3bd94f1016494bc1fad4f4b816524f8cbdd068f0caf94a1cec682ab75755327e4410267721e44f83d73a56e88b911051eb0a2f2ee1ffef5f2cf5419cbc81895cd7d290b70060ef80b727fd52", 143 | "asub": "U2FsdGVkX181J09umWprAgmLOaDyZXojQjLPlJ31G0LDgXHBgnNsFEOKgjqhKJ2vWaPP5Xmt8sIQLmB3YYkjQO1LhrV7sr0FDlwqjLhSimxmI1EnjOdEHyiE1RO7LV0O", 144 | "amsg": "U2FsdGVkX18J7Myet9yljBLtNMpqz86qWgmjrK/9WyP+LD9OVerohkl5jc791UOlU6cV4UFVhdwJHyQSMYNNDPOaJMhxlLF2tL7LIBDeGqPA2AlgWqe2qbF1JC+zjIgBR/+IUfbr0+gz4JUBydK3d1dJGPFYliQTqD7EOjv38No=", 145 | "acta": "U2FsdGVkX188zXRR3URQR2xedjftDOHD5E3k+ggKe+8F6MxW86464rl6y1ZhX3jY", 146 | "aimg": "U2FsdGVkX188AaU187LFzqaibpfoOXb+XkCNbsLpV29CrQOVjC9BfWpxwGXE9Er7OdJ63yblqFYCaqNoGAHCOg==", 147 | "atime": "1595083821" 148 | } 149 | } 150 | ``` 151 | 152 | ### Targeted Payload \(Type 3\) 153 | 154 | Targeted notification goes to a single subscriber of a channel, the notification payload in this case is not encrypted. 155 | 156 | ```text 157 | { 158 | "notification": { 159 | "title": "The title of your message displayed on screen (50 Chars)", 160 | "body": "The intended message displayed on screen (180 Chars)" 161 | }, 162 | "data": { 163 | "type": "3", 164 | "secret": "", 165 | "asub": "[Optional] The subject of the message displayed inside app (80 Chars)", 166 | "amsg": "[Optional] The intended message displayed inside app (500 Chars)", 167 | "acta": "[Optional] The cta link parsed inside the app", 168 | "aimg": "[Optional] The image url or youtube url which is shown inside the app", 169 | "atime": "[Optional] Epoch time for the notification to be shown or dispatch" 170 | } 171 | } 172 | ``` 173 | 174 | ## Payload Types in Discussion 175 | 176 | The following payloads are in discussion, please follow the appropriate git issue to participate in the discussion. 177 | 178 | {% hint style="info" %} 179 | Want a new payload type required by you or can be useful for EPNS protocol, please open an issue to start the discussion. 180 | {% endhint %} 181 | 182 | ### Multi-Targeted Payload \(Type 4\) 183 | 184 | Multi-Targeted notification goes to a more than one subscriber of a channel, the notification payload in this case is not encrypted. The total number of subscribers supported is TBA. 185 | 186 | ```text 187 | { 188 | "notification": { 189 | "title": "The title of your message displayed on screen (50 Chars)", 190 | "body": "The intended message displayed on screen (180 Chars)" 191 | }, 192 | "data": { 193 | "type": "4", 194 | "secret": "", 195 | "asub": "[Optional] The subject of the message displayed inside app (80 Chars)", 196 | "amsg": "[Optional] The intended message displayed inside app (500 Chars)", 197 | "acta": "[Optional] The cta link parsed inside the app", 198 | "aimg": "[Optional] The image url or youtube url which is shown inside the app", 199 | "atime": "[Optional] Epoch time for the notification to be shown or dispatch" 200 | }, 201 | "recipients": { 202 | [0xAb...], 203 | ... 204 | [0xEb...] 205 | } 206 | } 207 | ``` 208 | 209 | ### Multiplex Payload \(Type 5\) 210 | 211 | Multiplex notification goes to a more than one subscriber of a channel, the notification payload in this case depends on the inner payloads defined. The total number of subscribers supported is TBA. 212 | 213 | ```text 214 | { 215 | "data": { 216 | "type": "5", 217 | "meta": { 218 | { 219 | "notification": { 220 | "title": "The title of your message displayed on screen (50 Chars)", 221 | "body": "The intended message displayed on screen (180 Chars)" 222 | }, 223 | "data": { 224 | "type": "3", 225 | "secret": "", 226 | "asub": "[Optional] The subject of the message displayed inside app (80 Chars)", 227 | "amsg": "[Optional] The intended message displayed inside app (500 Chars)", 228 | "acta": "[Optional] The cta link parsed inside the app", 229 | "aimg": "[Optional] The image url or youtube url which is shown inside the app", 230 | "atime": "[Optional] Epoch time for the notification to be shown or dispatch" 231 | } 232 | }, 233 | ... 234 | { 235 | "notification": { 236 | "title": "The title of your message displayed on screen (50 Chars)", 237 | "body": "The intended message displayed on screen (180 Chars)" 238 | }, 239 | "data": { 240 | "type": "2", 241 | "secret": "No more than 15 characters, encrypted using public key of the intended recipient", 242 | "asub": "encrypted by secret using AES | [Optional] The subject of the message displayed inside app (80 Chars)", 243 | "amsg": "encrypted by secret using AES | [Optional] The intended message displayed inside app (500 Chars)", 244 | "acta": "encrypted by secret using AES | [Optional] The cta link parsed inside the app", 245 | "aimg": "encrypted by secret using AES | [Optional] The image url which is shown inside the app", 246 | "atime": "[Optional] Epoch time for the notification" 247 | } 248 | } 249 | } 250 | } 251 | } 252 | ``` 253 | 254 | {% hint style="info" %} 255 | Multi-Targeted payload will not be supported with multiplex payload. 256 | {% endhint %} 257 | 258 | ## Protocol Interfacing \(Advanced User\) 259 | 260 | All of the payloads are uploaded as JSON format in decentralized storage solutions \(**or in some special future cases, even centralized ones**\). The EPNS JS Library interfaces with Ethereum Push Notification Service protocol and calls: 261 | 262 | ```text 263 | sendNotification(address _recipient, bytes _identity) 264 | ``` 265 | 266 | | Parameter | Sub Field | Description | 267 | | :--- | :--- | :--- | 268 | | **\_recipient** | | Differs with the payload type, broadcast and special multi payload notifications have the channel address as the recipient address. | 269 | | **\_identity** | | The identity field consists of the following parameters joined together with a delimiter. | 270 | | | delimiter | The delimiter **+** is used for joining the fields together, this is done to optimize the payload written on chain. | 271 | | | pushtype | Indicates service wants to push the notifications out and can in the future be segmented to different platforms push \(i.e. : 1 for every platform, 2 for mobile, 3 for web browsers, etc\). | 272 | | | payloadtype | Indicates the payload type which is getting written on chain | 273 | | | payloadhash | Indicates the hash of the payload through which payload data can be obtained, payload type not only indicates the content of notification but also the storage implementation stored. | 274 | 275 | {% hint style="success" %} 276 | Example identity: **1+2+QmcdzjicUnxv8ASKKSgEEYjhK7symwxqDG4BeCS82rdNBk** 277 | {% endhint %} 278 | 279 | {% hint style="info" %} 280 | Always recommended to interface with **EPNS JS Library** for abstracting these details out. 281 | {% endhint %} 282 | 283 | -------------------------------------------------------------------------------- /sending-notifications/server-workflow.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Workflow for sending notification via third party server model 3 | --- 4 | 5 | # From Server 6 | 7 | ## Server integration workflow 8 | 9 | EPNS allows various ways to integrate the protocol into your service. The following flow shows how your server can integrate and send notification to the protocol. 10 | 11 | ![](../.gitbook/assets/inputserver.png) 12 | 13 | ### Sending notification via the server 14 | 15 | 1. Use your internal logic to figure out what notification you want to send \(ie: alerting users on some smart contract event, some action of theirs, movement in their wallets, a podcast or post from your end, etc\). 16 | 2. Form the JSON payload using our JS Library or your which you want to send as notification. Please check [Notification Payload Types](notification-payload-types.md) for supported payload types and their requirements. 17 | 3. Interact with protocol using our JS Library or your own. 18 | 4. That's it, sit back and relax, we will take it on from here. 19 | 20 | {% hint style="info" %} 21 | We run several channels on our NodeJS server implementation like **Btc Price Tracker, ENS Domain Expiry, EthGas Fee Tracker, Wallet Movement Alerter, etc**. 22 | 23 | Contact us at [admin@epns.io](mailto://admin@epns.io) incase you want access to that repo for faster implementation / examples. 24 | {% endhint %} 25 | 26 | -------------------------------------------------------------------------------- /sending-notifications/smart-contract-workflow.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Workflow for sending notification via third party smart contract model 3 | --- 4 | 5 | # From Smart Contract 6 | 7 | ## Smart Contract workflow 8 | 9 | EPNS allows various ways to integrate the protocol into your service. The following flow shows how your server can integrate and send notification to the protocol. 10 | 11 | ![](../.gitbook/assets/inputsmartcontract.png) 12 | 13 | ### Sending notification via the smart contract 14 | 15 | 1. Use your internal logic to figure out what notification you want to send \(i.e. alerting users on some smart contract event, user actions, movement in their wallets, a podcast or post from your end, etc\). 16 | 2. This can be done by either having internal logic cooked in your protocol or better yet having a function which you can call from outside which can interact with our protocol. 17 | 3. Please check [Notification Payload Types](notification-payload-types.md) for supported payload types and their requirements. 18 | 4. Either pass the **hash** of the content you want to send to **EPNS protocol \(recommended\)**. 19 | 5. That's it, sit back and relax, we will take it on from here. 20 | 21 | {% hint style="info" %} 22 | The protocol also supports sending notification 23 | 24 | 1. Alternatively, pass the payload in bytes to the protocol with appropriate payload. 25 | {% endhint %} 26 | 27 | -------------------------------------------------------------------------------- /tenets.md: -------------------------------------------------------------------------------- 1 | # Tenets 2 | 3 | What we want to focus on, growing document. 4 | 5 | 1. Security - Users need to be protected, their notifications \(especially secrets\) should be only accessible to them. 6 | 2. User Experience - Users should be expected to do minimal things in setup or otherwise, every thing should be automagical. 7 | 3. Decentralization - Every mapping, settings, notifications, etc should be stored \(indirectly - ipfs, etc or directly\) on decentralized solutions. ie: aim to be platform agnostic. 8 | 4. Flexibility - Notifications, Features should work exactly the same anywhere regardless of the platform user is on. ie: dApp, Mobile App, Web Browser, favorite wallets, etc. 9 | 5. Low Cost / Protocol Optimization - The protocol should be optimized in every way possible to decrease the cost to the user without compromising on features. 10 | 11 | -------------------------------------------------------------------------------- /tenets/README.md: -------------------------------------------------------------------------------- 1 | # Tenets 2 | What we want to focus on, growing document. 3 | 4 | 1. Security - Users need to be protected, their notifications (especially secrets) should be only accessible to them. 5 | 2. User Experience - Users should be expected to do minimal things in setup or otherwise, every thing should be automagical. 6 | 3. Decentralization - Every mapping, settings, notifications, etc should be stored (indirectly - ipfs, etc or directly) on decentralized solutions. ie: aim to be platform agnostic. 7 | 4. Flexibility - Notifications, Features should work exactly the same anywhere regardless of the platform user is on. ie: dApp, Mobile App, Web3 Providers, etc. 8 | 5. Low Cost / Protocol Optimization - The protocol should be optimized in every way possible to decrease the cost to the user without compromising on features. 9 | --------------------------------------------------------------------------------