Ethos-Protocol uses Firebase Cloud Messaging (FCM) HTTP v1 API to deliver push notifications to iOS, Android, and web clients.
Add these to your .env (see .env.example):
FCM_SERVER_KEY=<OAuth2 access token or legacy server key>
FCM_PROJECT_ID=<your-firebase-project-id>
NOTIFICATION_SCHEDULER_INTERVAL_SECS=60Get your project ID from the Firebase Console → Project Settings.
| Type | Trigger | Default |
|---|---|---|
expiry_warning |
TTL drops below warning_hours_before |
enabled, 24h |
check_in_reminder |
Scheduled by owner | enabled |
vault_released |
Vault released to beneficiary | enabled |
vault_paused |
Vault paused | enabled |
POST /notifications/register
{ "owner": "<stellar-address>", "token": "<fcm-token>", "platform": "ios|android|web" }
DELETE /notifications/register
{ "owner": "<stellar-address>", "token": "<fcm-token>", "platform": "ios|android|web" }
GET /notifications/preferences?owner=<stellar-address>
→ { "owner": "…", "expiry_warning_enabled": true, "check_in_reminder_enabled": true,
"vault_released_enabled": true, "warning_hours_before": 24 }
PUT /notifications/preferences
{ "owner": "…", "expiry_warning_enabled": false, "warning_hours_before": 48 }
All fields except owner are optional — only provided fields are updated.
GET /notifications/delivery?owner=<stellar-address>
→ [{ "notification_id": "…", "vault_id": "…", "status": "sent|failed",
"sent_at": "ISO8601", "provider_response": "projects/…/messages/…" }]
The background scheduler runs every NOTIFICATION_SCHEDULER_INTERVAL_SECS seconds and delivers all due pending notifications.
Expiry warnings are scheduled automatically when a vault is loaded — they fire warning_hours_before hours before the vault's TTL expires.
Immediate notifications (vault released, vault paused) are scheduled at the time of the event and delivered on the next scheduler tick.
Every send attempt (success or failure) is written to the DeliveryStore with:
status:sentorfailedprovider_response: FCM message ID on success, error string on failure
Query the delivery log via GET /notifications/delivery?owner=….
- Add
google-services.jsontoapp/ - Implement
FirebaseMessagingService.onNewToken→ callPOST /notifications/register - Handle
onMessageReceivedfor foreground messages
- Upload APNs key in Firebase Console → Project Settings → Cloud Messaging
- Call
UIApplication.registerForRemoteNotifications()on launch - In
AppDelegate.application(_:didRegisterForRemoteNotificationsWithDeviceToken:)→ callPOST /notifications/register
VaultEvent / TTL check
│
▼
NotificationService.schedule_expiry_warning()
NotificationService.schedule_immediate()
│
▼ (every NOTIFICATION_SCHEDULER_INTERVAL_SECS)
NotificationService.flush_pending()
│
├─ check NotificationPreferences (skip if disabled)
├─ look up DeviceTokens for owner
▼
FcmClient.send() → FCM HTTP v1 API
│
▼
DeliveryRecord written (sent / failed)