You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The EquipChain platform needs to notify external services when specific on-chain events occur, such as meter reading submissions, contract state changes, or system alerts. This issue implements a webhook system that allows registered external URLs to receive HTTP POST notifications containing event data in JSON format.
The webhook system must include: Webhook Registration — an admin endpoint to register webhooks with a URL, event type filter, optional secret for HMAC signing, and active/inactive status; Event Dispatching — an internal event emitter that dispatches events to all matching registered webhooks. The dispatch should be asynchronous and non-blocking, using a background queue (Issue #18) for reliable delivery with retry logic; Payload Signing — each webhook request must include an HMAC-SHA256 signature header (X-Webhook-Signature) computed from the request body and the shared secret, allowing the recipient to verify authenticity; Retry and Logging — failed deliveries (non-2xx responses or timeouts) should be retried up to 3 times with exponential backoff (1min, 5min, 15min). All delivery attempts and results should be logged for audit and debugging.
The webhook event format should follow a standard structure: { id: "evt_...", type: "meter.reading.created", created: "ISO8601 timestamp", data: { ... event-specific payload }, webhookId: "wh_..." }. The system should support at least the following event types: meter.reading.created, meter.reading.updated, contract.state.changed, system.alert.high, user.registered, and admin.action.
Architecture: New src/services/webhook.js containing webhook registration store, event emitter, and dispatch logic. New src/routes/admin/webhooks.js for CRUD operations on webhook registrations. Webhook delivery runs in the background to avoid blocking API responses.
Impact: Webhooks are a critical integration point for external partners. This feature enables real-time data synchronization with external systems, automated billing triggers, and integration with third-party monitoring services.
Step-by-Step Implementation Guide
Create Webhook Service: Write src/services/webhook.js implementing: registerWebhook(url, events, secret), unregisterWebhook(id), listWebhooks(), dispatchEvent(eventType, payload), deliverWebhook(webhook, event). Use an in-memory store for initial implementation (upgrade to database later). Implement the delivery function with fetch() (Node 18+) and HMAC signing.
Create Admin Webhook Routes: Write src/routes/admin/webhooks.js with POST /api/admin/webhooks (register), GET /api/admin/webhooks (list), DELETE /api/admin/webhooks/:id (unregister), PATCH /api/admin/webhooks/:id (update). Mount under admin routes with admin authentication.
Create Event Emitter Integration: Create an event emitter instance accessible across the app. In services that produce events (meter readings, contract changes), emit events that the webhook service listens to. Wire this in src/index.js or an app bootstrap function.
Write Tests: Create tests/unit/webhook.test.js testing registration, event dispatching (using nock or similar to mock HTTP), HMAC signature generation, retry logic, and delivery failure handling. Create tests/integration/webhook.test.js testing full flow via API with a test HTTP server as the webhook receiver.
Verification & Testing Steps
Register a webhook pointing to a webhook testing service (webhook.site or a local listener) via POST /api/admin/webhooks.
Trigger an event (e.g., create a meter reading) and verify the webhook receiver gets a POST request with the correct JSON payload.
Verify the X-Webhook-Signature header is present and valid by computing HMAC-SHA256 on the receiver side and comparing.
Configure a webhook with an invalid URL — verify the system retries 3 times with exponential backoff (check logs).
List registered webhooks via GET /api/admin/webhooks and verify all details are correct. Delete a webhook and verify no further events are dispatched to it.
Description
The EquipChain platform needs to notify external services when specific on-chain events occur, such as meter reading submissions, contract state changes, or system alerts. This issue implements a webhook system that allows registered external URLs to receive HTTP POST notifications containing event data in JSON format.
The webhook system must include: Webhook Registration — an admin endpoint to register webhooks with a URL, event type filter, optional secret for HMAC signing, and active/inactive status; Event Dispatching — an internal event emitter that dispatches events to all matching registered webhooks. The dispatch should be asynchronous and non-blocking, using a background queue (Issue #18) for reliable delivery with retry logic; Payload Signing — each webhook request must include an HMAC-SHA256 signature header (
X-Webhook-Signature) computed from the request body and the shared secret, allowing the recipient to verify authenticity; Retry and Logging — failed deliveries (non-2xx responses or timeouts) should be retried up to 3 times with exponential backoff (1min, 5min, 15min). All delivery attempts and results should be logged for audit and debugging.The webhook event format should follow a standard structure:
{ id: "evt_...", type: "meter.reading.created", created: "ISO8601 timestamp", data: { ... event-specific payload }, webhookId: "wh_..." }. The system should support at least the following event types:meter.reading.created,meter.reading.updated,contract.state.changed,system.alert.high,user.registered, andadmin.action.Technical Context & Impact
node:cryptofor HMAC signing (built-in). A background job mechanism from Issue [Feature] Implement Background Job Queue for Scheduled Tasks (Billing, Reports, Sync) #18 (or a simple in-memory queue for initial implementation). Node.js built-ineventsmodule for the event emitter.src/services/webhook.jscontaining webhook registration store, event emitter, and dispatch logic. Newsrc/routes/admin/webhooks.jsfor CRUD operations on webhook registrations. Webhook delivery runs in the background to avoid blocking API responses.Step-by-Step Implementation Guide
src/services/webhook.jsimplementing:registerWebhook(url, events, secret),unregisterWebhook(id),listWebhooks(),dispatchEvent(eventType, payload),deliverWebhook(webhook, event). Use an in-memory store for initial implementation (upgrade to database later). Implement the delivery function withfetch()(Node 18+) and HMAC signing.deliverWebhook()using a queue. On failure, schedule retry with setTimeout (or use Issue [Feature] Implement Background Job Queue for Scheduled Tasks (Billing, Reports, Sync) #18's job queue). Track delivery attempts with a max of 3 retries. Log each attempt with timestamp, status, and response body.src/routes/admin/webhooks.jswithPOST /api/admin/webhooks(register),GET /api/admin/webhooks(list),DELETE /api/admin/webhooks/:id(unregister),PATCH /api/admin/webhooks/:id(update). Mount under admin routes with admin authentication.src/index.jsor an app bootstrap function.tests/unit/webhook.test.jstesting registration, event dispatching (using nock or similar to mock HTTP), HMAC signature generation, retry logic, and delivery failure handling. Createtests/integration/webhook.test.jstesting full flow via API with a test HTTP server as the webhook receiver.Verification & Testing Steps
POST /api/admin/webhooks.X-Webhook-Signatureheader is present and valid by computing HMAC-SHA256 on the receiver side and comparing.GET /api/admin/webhooksand verify all details are correct. Delete a webhook and verify no further events are dispatched to it.