Documentation Index
Fetch the complete documentation index at: https://docs.peaq.xyz/llms.txt
Use this file to discover all available pages before exploring further.
Events are the atomic units of a machine’s financial history. The EventRegistry contract stores them onchain; the MCR scoring pipeline reads them to compute credit ratings.
Two event types
| Type | Value | Description |
|---|
| Revenue | 0 | The machine earned money. value carries the amount as a minor-unit integer (cents for USD/HKD, whole units for JPY/KRW) in the event’s currency; the MCR scoring pipeline normalizes to USD cents via FX at the event timestamp. Single-event submitEvent resolves an omitted currency to "USD" for revenue and "" for activity; batch submit requires an explicit currency per event. |
| Activity | 1 | The machine performed an action (telemetry, data generation, task completion). value may be 0. currency must be empty (""); non-empty currency on an activity event reverts InvalidCurrencyShape. |
Both SDKs export these as constants:
import {
EVENT_TYPE_REVENUE, // 0
EVENT_TYPE_ACTIVITY, // 1
} from "@peaqos/peaq-os-sdk";
MachineEvent schema
Every event stored in the EventRegistry follows this structure:
The SDKs expose the stored struct as MachineEvent (with dataHash / data_hash as a 32-byte keccak256). The SDK input type SubmitEventParams takes rawData / raw_data bytes instead; the SDK computes the hash for you before the call.
| Field | Type | Description |
|---|
machineId | uint256 | Machine identity from IdentityRegistry. Primary key linking event to machine. |
eventType | uint8 | 0 = revenue, 1 = activity. |
value | uint256 | Amount earned (revenue) or metric value (activity). May be 0 for activity events. Revenue events express value as an ISO 4217 minor-unit integer (cents for USD/HKD, whole units for JPY/KRW) in the event’s currency. |
currency | string | Revenue events: 3-10 char uppercase alphanumeric ISO 4217 code (e.g. "USD", "HKD", "JPY"). Activity events: empty string "". Validated on-chain. |
timestamp | uint256 | Unix timestamp when the event occurred, not when it was submitted. |
dataHash | bytes32 | keccak256(raw_data). Raw data stays off-chain; hash proves integrity. |
trustLevel | uint8 | 0 = self-reported, 1 = on-chain verifiable, 2 = hardware-signed. |
sourceChainId | uint256 | Chain where the original activity occurred (e.g., 3338 for peaq, 8453 for Base). 0 for off-chain events. |
sourceTxHash | bytes32 | Transaction hash on the source chain. Combined with sourceChainId, creates a verifiable cross-chain link. Null for off-chain events. |
metadata | bytes | Arbitrary bytes stored on-chain alongside the event (4096-byte cap). The MCR API server parses JSON metadata into the event_data[].metadata object surfaced on /machine/{did} for machines with data_visibility: onchain; the SDK only writes raw bytes. |
Cross-chain revenue accounting
sourceChainId and sourceTxHash together form a cross-chain audit trail. When a machine earns revenue on Base, the proxy submits the event to the EventRegistry on peaq with sourceChainId = 8453 and the Base transaction hash. Any verifier can look up the transaction on the source chain and confirm the event happened.
| Scenario | sourceChainId | sourceTxHash |
|---|
| Revenue earned on Base | 8453 | Base transaction hash |
| Revenue earned on peaq | 3338 | peaq transaction hash |
| Off-chain telemetry | 0 | null (bytes32(0)) |
Data integrity via dataHash
Raw event data stays with the project (in their database, behind their API). The dataHash stored onchain is keccak256(raw_data), computed by the SDK before submission. This keeps gas costs at 32 bytes per event regardless of payload size, while anyone can fetch the raw data from the project’s data_api (set in the machine’s DID) and verify keccak256(fetched_data) == dataHash.
import { computeDataHash } from "@peaqos/peaq-os-sdk";
const rawData = new Uint8Array([1, 2, 3]);
const hash = computeDataHash(rawData);
// hash === "0x..." (keccak256)
Authorization
EventRegistry reads IdentityRegistry to verify submit authority. msg.sender must be one of:
| Path | Address | Use case |
|---|
| NFT owner | Identity NFT holder | The account that holds the Identity NFT submits directly. |
| Machine wallet | machineWalletOf(machineId) | The machine’s registered wallet submits. Typical for self-managed flows where the machine signs its own transactions. |
| Operator | operatorOf(machineId) | Assigned operator submits on behalf of the machine. Only valid when an operator has been set (non-zero). |
All three paths produce identical on-chain records: the machineId in the stored event always identifies the machine, regardless of who submitted.
Validation
The JS SDK exports validateSubmitEventParams, which checks all nine fields before any chain interaction:
import { validateSubmitEventParams } from "@peaqos/peaq-os-sdk";
validateSubmitEventParams({
machineId: 1,
eventType: 0,
value: 100, // $1.00 in cents
currency: "USD",
timestamp: Math.floor(Date.now() / 1000),
rawData: new Uint8Array([1, 2, 3]),
trustLevel: 1,
sourceChainId: 8453,
sourceTxHash: "0xabc...def",
metadata: new Uint8Array([]),
});
Key validation rules:
eventType must be 0 or 1
value must be a non-negative integer (subunit, per ISO 4217 minor units)
trustLevel must be 0, 1, or 2
sourceChainId must be a supported chain (0, 3338, or 8453)
- When
trustLevel is 1 (on-chain verifiable), sourceTxHash is required
rawData must be non-empty when provided (null is allowed, empty array is not)
currency on revenue events must match ^[A-Z0-9]{3,10}$; on activity events it must be ""
timestamp must be a positive integer; the EventRegistry contract additionally rejects timestamp > block.timestamp (FutureTimestamp revert)
metadata is capped at 4096 bytes on-chain (MetadataTooLarge revert above the limit)
Cross-links