On-Chain Event Subscription System via Push Protocol

We design and develop full-cycle blockchain solutions: from smart contract architecture to launching DeFi protocols, NFT marketplaces and crypto exchanges. Security audits, tokenomics, integration with existing infrastructure.
Showing 1 of 1 servicesAll 1306 services
On-Chain Event Subscription System via Push Protocol
Medium
~2-3 business days
FAQ
Blockchain Development Services
Blockchain Development Stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1214
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    852
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_logo-advance_0.png
    B2B Advance company logo design
    561
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    823

Developing a subscription system for on-chain events via Push

Push Protocol (formerly EPNS — Ethereum Push Notification Service) is a decentralized notification layer for Web3. Users subscribe to a channel through a wallet signature, receive push notifications in the app, email, or mobile phone. For a dApp, this solves the problem of "user doesn't know what's happening with their position" without requiring email storage.

Push Protocol architecture

Push works at three levels:

  1. On-chain part — a contract on Ethereum mainnet (and Polygon) records channel creation and user subscriptions
  2. Push nodes — a decentralized network of nodes that deliver notifications
  3. SDK@pushprotocol/restapi and @pushprotocol/socket for interaction

A channel is a smart contract or EOA with the right to send notifications to its subscribers. Channel creation requires staking 50 PUSH tokens.

Integration into dApp frontend

User channel subscription

import { PushAPI, CONSTANTS } from '@pushprotocol/restapi'
import { useWalletClient } from 'wagmi'

export function useChannelSubscription(channelAddress: string) {
  const { data: walletClient } = useWalletClient()
  
  const subscribe = async () => {
    if (!walletClient) return
    
    const pushUser = await PushAPI.initialize(walletClient, {
      env: CONSTANTS.ENV.PROD,
    })
    
    await pushUser.notification.subscribe(
      `eip155:1:${channelAddress}`, // CAIP-10 format
    )
  }
  
  const checkSubscription = async (userAddress: string) => {
    const subscriptions = await PushAPI.user.getSubscriptions({
      user: `eip155:1:${userAddress}`,
      env: CONSTANTS.ENV.PROD,
    })
    return subscriptions.some((s: any) => 
      s.channel.toLowerCase() === channelAddress.toLowerCase()
    )
  }
  
  return { subscribe, checkSubscription }
}

Subscription requires a transaction signature (or EIP-712 signature for gasless via Push relay). Users don't need to pay gas for most operations — Push supports gasless subscriptions via meta-transactions.

Display notifications in UI

import { PushAPI, CONSTANTS } from '@pushprotocol/restapi'

export function useNotifications(userAddress: string) {
  const [notifications, setNotifications] = useState([])
  
  useEffect(() => {
    const fetchNotifications = async () => {
      const notifs = await PushAPI.user.getFeeds({
        user: `eip155:1:${userAddress}`,
        env: CONSTANTS.ENV.PROD,
        limit: 20,
      })
      setNotifications(notifs)
    }
    
    fetchNotifications()
  }, [userAddress])
  
  return notifications
}

Real-time via WebSocket

import { createSocketConnection, CONSTANTS } from '@pushprotocol/socket'

const pushSocket = createSocketConnection({
  user: `eip155:1:${userAddress}`,
  env: CONSTANTS.ENV.PROD,
  socketOptions: { autoConnect: false },
})

pushSocket.connect()

pushSocket.on(CONSTANTS.SOCKET.EVENTS.USER_FEEDS, (notification) => {
  // Show toast notification
  showToast({
    title: notification.payload.notification.title,
    body: notification.payload.notification.body,
  })
})

Sending notifications from the backend

Notifications about on-chain events are sent from the server: monitor events through RPC/webhook, and when an event occurs, send a notification through the Push SDK.

import { PushAPI, CONSTANTS } from '@pushprotocol/restapi'
import { ethers } from 'ethers'

const CHANNEL_PRIVATE_KEY = process.env.PUSH_CHANNEL_PRIVATE_KEY!

async function sendLiquidationWarning(userAddress: string, healthFactor: number) {
  const signer = new ethers.Wallet(CHANNEL_PRIVATE_KEY)
  
  const pushUser = await PushAPI.initialize(signer, {
    env: CONSTANTS.ENV.PROD,
  })
  
  await pushUser.channel.send([`eip155:1:${userAddress}`], {
    notification: {
      title: 'Liquidation Warning',
      body: `Health factor dropped to ${healthFactor.toFixed(2)}. Add collateral.`,
    },
    payload: {
      title: 'Liquidation Warning',
      body: `Health factor: ${healthFactor.toFixed(2)}`,
      cta: 'https://yourdapp.com/positions',
      category: CONSTANTS.NOTIFICATION.TYPE.TARGETED,
    },
  })
}

Monitoring on-chain events

Push Protocol is a delivery layer, but you need to implement event triggering yourself. Monitoring patterns:

Polling via RPC — a cron job polls getLogs or readContract every N seconds. Simple, reliable, but latency equals the polling interval.

Alchemy Notify / QuickNode Streams — webhook on on-chain event. Minimal latency (~1 block), but vendor lock-in.

WebSocket subscriptionseth_subscribe via WSS endpoint, handle events in real-time:

const wsClient = createPublicClient({
  chain: mainnet,
  transport: webSocket(process.env.ALCHEMY_WSS_URL),
})

wsClient.watchContractEvent({
  address: lendingPoolAddress,
  abi: lendingPoolAbi,
  eventName: 'HealthFactorUpdated',
  onLogs: async (logs) => {
    for (const log of logs) {
      const { user, healthFactor } = log.args
      if (healthFactor < parseUnits('1.1', 18)) {
        await sendLiquidationWarning(user, Number(formatUnits(healthFactor, 18)))
      }
    }
  },
})

Typical use cases

  • DeFi: liquidation warnings (health factor < threshold)
  • DEX: limit order execution
  • NFT: bid on your token, floor price changes
  • DAO: new proposal for voting
  • Bridge: transaction completed on another network
  • Yield: APY dropped below target

Integrating Push Protocol into an existing dApp with several notification types — 2–3 days. Includes: creating a channel in Push, setting up on-chain event monitoring, subscription component in UI, and real-time WebSocket notifications.