A demo implementation showcasing push notifications for transaction status updates in Embedded Wallets, replacing the traditional polling-based approach with an efficient push-based model. Each notification is associated with a specific walletId, enabling accurate delivery of transaction updates to the corresponding wallet instance.
This backend service enables real-time transaction status notifications across multiple platforms:
- Android (Firebase Cloud Messaging)
- iOS (Apple Push Notification Service)
- Web Browsers (FCM / Web Push API with VAPID)
- Eliminates constant polling for transaction status
- Reduces server load and API calls
- Provides immediate status updates
- Supports multiple platforms with a unified API
-
Client Applications
- Register devices for push notifications
- Send push tokens to backend during authentication
- Handle incoming notifications and trigger UI updates
-
Backend Server
- Manages device tokens and subscriptions
- Processes Fireblocks webhooks
- Distributes notifications to relevant devices
- Handles cross-platform notification delivery
-
Push Services
- Firebase Cloud Messaging (FCM) for Android/Web
- APNs for iOS
- Web Push API with VAPID for browsers
-
Fireblocks Integration
- Webhook processing for transaction lifecycle events
- Status change detection and notification triggering
-
Device Registration
LoadingsequenceDiagram Client->>Backend: Register device token Backend->>Database: Store token & platform info Backend->>Client: Registration confirmed
-
Transaction Updates
LoadingsequenceDiagram Fireblocks->>Backend: Transaction status webhook Backend->>Database: Look up user devices Backend->>Push Service: Send notifications Push Service->>Client: Deliver notification
- Node.js ≥ 20
- SQL database
- Firebase project (for FCM)
- VAPID keys (for Web Push)
-
Clone the repository
git clone git@github.com:fireblocks/ew-backend-demo.git cd ew-backend-demo -
Install dependencies
yarn install
-
Configure environment variables
cp .env.example .env # Edit .env with your configuration -
Run database migrations
yarn migration:run
-
Start the server
yarn dev
Required environment variables:
##### Server #####
PORT=3000
NODE_ENV=development
##### Database #####
DB_HOST=localhost
DB_PORT=3306
DB_USERNAME=db_user
DB_PASSWORD=db_pwd
DB_NAME=ew_demo
##### Authentication #####
JWKS_URI=your-jwks-uri
ISSUER=your-issuer
AUDIENCE=your-audience
##### Fireblocks Webhook Public Key #####
FIREBLOCKS_WEBHOOK_PUBLIC_KEY= "-----BEGIN PUBLIC KEY-----\nMII...""
##### Firebase Service Account #####
FIREBASE_SERVICE_ACCOUNT_PATH=path-to-yor-service-account-file
##### Push Notifications #####
VAPID_SUBJECT=mailto:your-email@example.com
VAPID_PUBLIC_KEY=your-vapid-public-key
VAPID_PRIVATE_KEY=your-vapid-private-key
##### CORS Origins #####
ORIGIN_WEB_SDK=http://localhost:3000, https://your-domain.comThe FIREBASE_SERVICE_ACCOUNT_PATH environment variable should point to a Firebase service account JSON file. This file is required for the backend to authenticate with Firebase Cloud Messaging (FCM) and send push notifications to Android and web clients.
How to obtain the service account file:
- Go to the Firebase Console and select your project.
- Navigate to Project Settings (gear icon) > Service Accounts.
- Click Generate new private key under the Firebase Admin SDK section.
- Download the generated JSON file and save it securely (e.g.,
firebase-service-account.json). - Set the
FIREBASE_SERVICE_ACCOUNT_PATHvariable in your.envfile to the path of this JSON file (relative to the project root or as an absolute path).
Example:
FIREBASE_SERVICE_ACCOUNT_PATH=./firebase-service-account.jsonSecurity Best Practices:
- Never commit your service account file to version control. Add it to your
.gitignore. - Store the file securely and restrict access to only trusted team members.
- Rotate the key if you suspect it has been compromised.
VAPID (Voluntary Application Server Identification) keys are required for Web Push notifications. These keys allow push services to identify your application server and ensure that only your server can send push notifications to your users.
How to generate VAPID keys:
-
Using the web-push library (recommended):
npx web-push generate-vapid-keys
-
Using Firebase CLI:
firebase login firebase projects:list firebase use <your-project-id> firebase messaging:generate-vapid-key
-
Using the Firebase Console:
- Go to the Firebase Console and select your project
- Navigate to Project Settings (gear icon) > Cloud Messaging
- Under the Web configuration section, click Generate key pair
- Copy the generated key pair
Setting up VAPID keys in your environment:
VAPID_SUBJECT=mailto:your-email@example.com
VAPID_PUBLIC_KEY=your-vapid-public-key
VAPID_PRIVATE_KEY=your-vapid-private-keyImportant notes:
- The
VAPID_SUBJECTshould be a valid email address or URL that identifies your application - The public key will be used by client applications to subscribe to push notifications
- The private key is used by your server to sign push messages
- Never expose your VAPID private key in client-side code or commit it to version control
- The same VAPID key pair should be used consistently across your application
Client-side usage:
Your web clients will need the public key to register for push notifications. The backend exposes this via the /api/notifications/vapid-public-key endpoint.
src/
├── controllers/ # Request handlers
├── middleware/ # Auth and webhook middleware
├── migrations/ # Database migrations
├── model/ # Database models
├── routes/ # API route definitions
├── services/ # Business logic
├── types/ # TypeScript type definitions
└── util/ # Utility functions
client/
├── examples/
│ ├── react/ # React integration examples
│ └── web/ # Web worker examples
POST /api/notifications/register-token
Content-Type: application/json
Authorization: Bearer your-token
{
"token": "firebase-device-token",
"platform": "android|ios|web-fcm",
"walletId": "your-embedded-wallet-id",
"deviceId": "optional-device-id"
}POST /api/notifications/register-subscription
Content-Type: application/json
Authorization: Bearer your-token
{
"subscription": {
"endpoint": "https://push-service.url",
"keys": {
"auth": "auth-secret",
"p256dh": "public-key"
}
},
"walletId": "your-embedded-wallet-id"
}GET /api/notifications/vapid-public-key- All endpoints require JWT authentication
- Push tokens are tied to authenticated sessions
- Notification payloads contain minimal data
- Rate limiting prevents abuse
- CORS is configured for allowed origins only
- HTTPS required for web push
yarn testyarn lint
yarn format- Fork the repository
- Create a feature branch
- Commit your changes
- Push to the branch
- Create a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.