Skip to main content
An attestation is a device-signed statement that a specific action happened, with specific parameters, at a specific time. KineticVM writes each one into the ERC-8004 Validation Registry, the standard place where onchain agents collect verifiable claims about their work.

The action proof

The device signs an EIP-712 ActionProof:
The domain is name = "KineticAttestor", version = "1". The requestURI is hashed into the signature, so it cannot be swapped after signing. As with claim tickets, the device asks the contract for the digest (hashActionProof) and signs that.

What the attestor checks

Anyone can submit a signed proof to KineticAttestor.attest(proof, signature). In practice the device submits its own. The attestor accepts it only if every check passes:
1

The signer is the active device

The signature must recover to KineticRegistry.activeDevice(agentId). A revoked key, a rotated-out key, or a key whose NFT changed hands is rejected.
2

The nonce is fresh

nonceUsed[agentId][nonce] must be false. Otherwise NonceUsed.
3

The proof is recent

timestamp may be at most 10 minutes old (StaleProof) and at most 2 minutes in the future (FutureProof).
4

The attestor is an operator on the agent

The owner must have approved the attestor with setApprovalForAll or approve. Otherwise NotOperator. ERC-8004 only lets an owner or operator open a validation request, and this is how the owner consents.

What gets written

The attestor then computes a request hash and writes two calls to the Validation Registry:
Finally it emits:
Anyone can later call getValidationStatus(requestHash) on the Validation Registry and get back the validator, agent, response, response hash, and tag. That lookup is the foundation of buyer verification.

When the device attests

When [chain] is enabled, the runtime wraps the actuator tools gpio_write, gpio_rpi_write, gpio_rpi_blink, and set_device. After one of them succeeds, the runtime attests it automatically:
  • action is the tool name,
  • the parameters are the tool’s JSON arguments,
  • requestURI is kinetic://actuator/<tool name>.
The tool’s output gets a line appended with the transaction hash, or with the error if the attestation failed. A failed tool call is never attested.
Plugin tools are not wrapped automatically. If a plugin drives a motor through its own path, the SOP or the model should call monad_attest after the operation completes.

Gas and nonces

The device pays gas for its attestations. Before submitting, the runtime checks its balance and tops up from the vault if it holds 1 MON or less. The runtime picks the nonce from the latest block time and tries up to four consecutive values until it finds one the attestor has not used, so two attestations in the same second do not collide.

Reading attestations

/status lists explorer links for the five most recent Attested transactions for the agent.

What an attestation proves

An attestation with response 100 proves that the device key bound to this agent signed this exact record at this time, and that the agent’s owner had authorized the attestor. It does not prove that the actuator physically moved, that a sensor reading was accurate, or that the device’s software was honest.
This is the same trust boundary as any signed log, made portable and public. What KineticVM adds is that the key is tied to an owned, revocable identity, the record cannot be edited after the fact, and anyone can check it without asking the operator. Stronger guarantees come from where the key lives (a secure element such as the SE050 makes key extraction impractical) and from correlating records across independent devices.