Skip to main content
peaqOS Verify is the attestation layer for peaqOS. It records two checks per machine, each called a topic: the chip topic says whether the machine’s secure element passed a hardware check, and the KYB topic says whether peaq has attested the business operating it after due diligence. Both records live in the AttestationRegistry on peaq, and anyone can read them through the Verify API, the SDKs and the CLI. Trust levels are self-declared on each . Verify attests the machine (not individual events). It is separate from the Hardware-signed level: the EventRegistry and the MCR do not check a machine’s Verify record when an event declares trustLevel: 2, so a counterparty that wants hardware assurance reads the chip topic next to the events. MCR says a machine makes money; Verify says whether the machine has a chip record and whether its operator has a KYB attestation.

What ships in v1

v1 is a beta. peaq is the only attester, the SDK and CLI surface is marked experimental, and the release covers reads and local chip preflight. Nothing in the SDKs or the CLI writes to the registry.

Two topics

Records live in the AttestationRegistry contract on peaq mainnet at 0x08804517BB1290ef0dDa8Db9Ff95255045d25f9A (see Smart contracts). It records attestations per machine and topic under one M-of-N attester quorum for the whole registry; v1 runs with peaq as the single attester. The two topics are reported independently: Each topic has its own status: unverified (no record yet; the normal state of an existing machine), verified, expired or revoked. Revocation wins over expiry. There is no aggregate “verified” flag.

Supported chip

v1 certifies one chip family: No TPM, software key, other Trust M variants or other secure elements. The chip proof binds an EVM chain ID and an EVM DID controller, so chip intake is for peaq-homed machines.

Read, preflight and intake

Read

GET /v1/verify/machines/{machineId} on the Verify API, VerifyReadClient in the JS and Python SDKs, and peaqos verify status in the CLI. Public, no key.

Chip preflight

Three pure functions in each SDK, and the prepare, controller-request and finalize stages of peaqos verify chip. They turn a challenge, the chip’s leaf certificate and two signatures into a canonical evidence document. They run on the machine, make no network call and hold no key.

Intake

peaq’s onboarding service requests the challenge with POST /v1/verify/chip/challenge and submits the evidence with POST /v1/verify/chip/evidence. Both routes take peaq’s onboarding token.

How it works

1

KYB

peaq runs due diligence on the operator’s business and records an attestation for its address. Every machine whose operator holds a valid attestation (not expired, not revoked) reads kyb.status: verified. This is a partnership process, not self-service.
2

Challenge

peaq’s onboarding service asks the Verify API for a challenge for one machine: a 32-byte nonce, the machine ID and DID, the current DID controller, the chain ID and an expiry at most five minutes out.
3

Chip preflight, on the machine

The SDK (or the CLI) builds the 32-byte prehash the chip must sign, checks the chip’s signature against the leaf certificate and the CA306 chain, builds the message the DID controller signs, then writes the canonical peaq.verify.chip-evidence/1 document.The SDK never touches the chip: a platform adapter reads the certificate from object 0xE0E0 and asks key 0xE0F0 to sign. Every stage rechecks the five-minute window.
4

Intake

The onboarding service submits the evidence. The Verify API reconstructs the machine context, revalidates every proof, consumes the challenge and stores the accepted evidence. A 202 accepted receipt is not a verified state: the chip status reads verified once peaq records the chip attestation in the registry.
5

Read

Anyone reads the machine’s record. The Verify API is authoritative: the SDK validates the response shape but does not re-derive chain state, and a successful local preflight never sets chip.status to verified on its own.
revocationStatus: "not_evaluated" in the preflight evidence means the SDK did not check certificate revocation locally. It is not a claim that the certificate is unrevoked; revocation is the attester’s decision.

Verify a chip, end to end

peaq’s onboarding service holds the onboarding token and calls the two intake routes (steps 1 and 6). The machine operator runs steps 2, 3 and 5 on the machine, and the machine’s DID controller signs step 4 on the machine or elsewhere. The machine needs the chip attached and peaq-os-cli 0.0.14 or newer installed. Steps 2 to 6 must finish before the challenge expires, at most five minutes after step 1.
1

Request a challenge (onboarding service)

The onboarding service calls POST /v1/verify/chip/challenge with the machine ID and keeps only the six fields peaqos verify chip accepts. The response also carries profile, protocol and verifier, which the CLI rejects; the SDK adds them back itself.
If curl exits non-zero, challenge.json holds the error envelope; read its detail.code and do not run jq.context.json goes to the machine. The clock starts now: expiresAt is at most 300 seconds away.
2

Read the chip certificate and build the prehash (machine)

Read the leaf certificate from object 0xE0E0, convert it to DER, and build the 32-byte prehash the chip signs:
prepare checks the certificate against the Infineon CA306 chain and the challenge against the clock before it writes anything.
3

Sign the prehash with the chip (machine)

Have key 0xE0F0 sign prehash.bin as is. Leave out -H: the prehash is already the digest, and hashing it again makes the signature fail. trustm_ecc_sign -o writes the signature with a 2-byte DER SEQUENCE header; the CLI wants the chip’s native form (r and s as two DER integers, no header), so strip the first two bytes:
controller-request verifies the chip signature against the certificate’s key and writes the message for the DID controller: a short canonical JSON text holding the chip signature and the transcript hash.
4

Sign the controller message (DID controller)

The current DID controller signs controller-message.bin once as an EIP-191 personal message. The CLI wants the raw 65-byte signature (r || s || v, v 27 or 28), not hex. With Foundry’s cast:
Any wallet that signs the file’s exact text with personal_sign works. The controller key never has to be on the machine: move controller-message.bin to the wallet and controller-signature.bin back.
5

Build the evidence (machine)

finalize checks that the controller signature recovers to the didController in the challenge and writes evidence.json in its final canonical form. Send that file to the onboarding service unchanged and delete the other artifacts.
6

Submit the evidence (onboarding service)

The onboarding service posts the file byte for byte to POST /v1/verify/chip/evidence:
202 with "status": "accepted" means every proof passed and the challenge is consumed. A 400 EVIDENCE_REJECTED or 409 CHALLENGE_EXPIRED is final for this challenge, and so is 404 CHALLENGE_NOT_FOUND: start again at step 1.
An accepted submission is not yet a verified chip. PEAQOS_VERIFY_API_URL=https://mcr.peaq.xyz peaqos verify status <machineId> reports Chip as verified once peaq records the chip attestation in the AttestationRegistry. Every --out path must not exist yet, and the CLI never overwrites a file. Run each new challenge in a fresh directory and never reuse artifacts from an earlier challenge.
If a stage fails with the challenge is outside its freshness window, either the challenge expired or the machine clock differs from the server’s. Every stage requires now < expiresAt <= now + 300 on the machine clock, so a clock that is behind can fail even on a fresh challenge. Sync the clock and request a new challenge.

Read a machine’s verification

Verify on peaq mainnet reads peaq-homed machines. A machine homed on Solana returns 503 VERIFY_READ_UNAVAILABLE, which the SDKs raise as an unavailable transport error and the CLI reports with exit code 2.
Every read returns the same shape: the machine ID and DID, its home chain, the DID controller and operator in their native address kinds, and one status per topic. You need peaq-os-cli 0.0.14 or newer, or peaq-os-sdk / @peaqos/peaq-os-sdk 0.10.0 or newer (Install), and the Verify API origin:
123 below is a placeholder and returns 404 MACHINE_NOT_FOUND; put in your own machine ID.
Illustrative response
  • The machine is addressed by its decimal machine ID (1 to 2^256-1, no leading zeros). A DID or an address is rejected.
  • An existing machine with both topics unverified is a normal result. An unknown machine is a 404 MACHINE_NOT_FOUND.
  • Reads are limited to 60 per minute per IP address. One call makes exactly one request with a five-second deadline and no retry.

Verify and the other functions

Activate

A machine needs a 2.0 machine ID and a DID before it can be verified. The chip challenge is issued against the current DID controller.

Qualify

MCR scores revenue and activity. Verify does not change the score; it is a separate signal a counterparty reads next to it.

Trust levels

The trust level is a field you set on each event. Verify does not set it, and the MCR does not check Verify when it weights Hardware-signed events; read the chip topic to see whether the machine’s secure element was attested.

Reference