What Is a Service Contract?
A Service Contract is a JavaScript mini-program that runs inside the FidesInnova Node's ZKP-enabled JavaScript runtime (IsolatedVM). It defines the logic that governs how your IoT device data is processed, shared, and monetized.
Service Contracts are the programmable layer of the FidesInnova platform. They turn raw MQTT data streams into intelligent, verifiable, monetizable data products — without requiring you to build a backend server.
📡 Data Processing
Subscribe to device MQTT topics, transform readings, aggregate across multiple devices, and forward results to dashboards or other services.
🔐 ZKP Generation
Call node.generateProof() to create a zk-SNARK proof for any processed data, then submit it to the blockchain for permanent verification.
💰 Monetization
Publish contracts to the Service Market. Other users install your contract, data flows to them, and payment flows to you — automatically.
⚡ Automation
React to sensor thresholds, time schedules, or blockchain events. Send notifications, trigger other devices, or open/close data streams conditionally.
Contract Anatomy
Every Service Contract has the same basic structure:
// service-contract.js — basic structure
// 1. Contract metadata (read by the Node and Service Market)
const CONTRACT = {
name: "Temperature Monitor",
version: "1.0.0",
author: "your-node-id",
devices: ["device-001"], // which devices this contract applies to
triggers: ["onSensorData", "onSchedule"],
price: 0.001 // per execution, for Service Market
};
// 2. Triggered on each MQTT message from subscribed devices
async function onSensorData(deviceId, reading, proof) {
// your logic here
}
// 3. Triggered on a schedule (cron-style)
async function onSchedule(timestamp) {
// hourly/daily aggregations
}
Blockly Visual Editor
If you prefer a no-code approach, the FidesInnova Node dashboard includes a Blockly visual editor — a drag-and-drop programming environment where you assemble logic from visual blocks.
Blockly is ideal for:
- Rapidly prototyping contract logic without writing JavaScript
- Non-developer team members building automations
- Teaching IoT automation concepts without programming prerequisites
- Generating the JavaScript code skeleton that developers can then extend
The Blockly editor supports all major contract features: reading device data, setting conditions (if/else), generating proofs, sending notifications, and publishing to the Service Market. It exports valid JavaScript that runs identically to hand-written contracts.
Writing Your First Contract
This complete example monitors air quality and generates a ZKP-verified record when PM2.5 exceeds safe levels:
const SAFE_PM25 = 35; // WHO guideline μg/m³
async function onSensorData(deviceId, reading) {
// Validate incoming data
if (!reading || reading.pm25 === undefined) return;
// Generate ZKP proof for this reading
const proof = await node.generateProof({
deviceId,
pm25: reading.pm25,
timestamp: Date.now()
});
// Store proof on blockchain
await node.submitToBlockchain(proof);
// Alert if threshold exceeded
if (reading.pm25 > SAFE_PM25) {
await node.sendNotification({
title: "⚠️ Air Quality Alert",
body: `PM2.5: ${reading.pm25} μg/m³ — above safe limit`,
proofId: proof.id
});
}
// Share verified data with market subscribers
await market.publishData({ pm25: reading.pm25, proof: proof.id });
}
Adding ZKP Proofs to Contract Outputs
Any value computed inside a Service Contract can itself be ZKP-proven. This extends the chain of cryptographic trust beyond individual device readings to aggregated analytics:
async function onSchedule() {
// Aggregate hourly readings from all devices
const readings = await node.queryHistory({
metric: 'pm25', window: '1h'
});
const avg = readings.reduce((a,b) => a+b) / readings.length;
// Prove the average — without revealing individual readings
const aggProof = await node.generateAggregateProof(readings, avg);
await node.submitToBlockchain(aggProof);
}
Event-Driven Patterns
Beyond onSensorData and onSchedule, Service Contracts support additional event triggers:
- onDeviceConnect / onDeviceDisconnect — react when a device comes online or goes offline (via MQTT LWT)
- onProofVerified — triggered when a proof submitted by this contract is confirmed on-chain
- onMarketInstall / onMarketUninstall — runs when another user installs or removes your contract from their node
- onCommand — receives commands from the mobile app or web dashboard to change contract parameters at runtime
Publishing to the Service Market
- In your Node dashboard, navigate to Service Contracts → My Contracts
- Select your tested contract and click Publish to Market
- Set a name, description, category, and pricing (per execution or flat monthly fee)
- Choose data fields to expose to subscribers — leave sensitive fields private
- Submit — your contract appears in the Service Market within minutes
- Monitor installs and revenue in the Market Analytics dashboard
Debugging & Monitoring
The FidesInnova Node dashboard provides a real-time contract log view. Common debugging techniques:
- Use
node.log(message) inside contracts — output appears in the dashboard log panel
- The proof submission queue shows pending and confirmed proofs with status
- The MQTT message inspector shows all incoming device messages in real time
- Use contract versioning — deploy a new version without removing the running one; roll back if issues occur