Skip to main content
Every KineticVM device is an agent in the ERC-8004 Identity Registry on Monad. The agent is an ERC-721 NFT. Whoever holds the NFT owns the machine. The device itself holds a separate device key that the registry binds to the agent. Two keys, two roles:

Owner wallet

Holds the agent NFT. Sets and relaxes limits, withdraws funds, rotates or revokes the device key, and can sell the machine by transferring the NFT.

Device key

Lives on the machine. Signs claim tickets and action proofs, pays within the vault caps, and relays owner-signed changes. Never owns the NFT and is never an operator on it.

The agent identity

The agent id is the token id that the ERC-8004 Identity Registry assigns at mint. The identity also carries an agentURI. The KineticVM claim page sets it to a small JSON document:
encoded as a data:application/json,… URI. The agent’s owner is always the live ownerOf(agentId) on the Identity Registry. KineticRegistry exposes the same value through ownerOfAgent(agentId) and never stores its own copy as the source of authority.

Claim tickets

Before the owner can claim a device, the device has to prove two things: that it holds its key, and which owner it agrees to serve. It does that by signing an EIP-712 claim ticket.
The EIP-712 domain is name = "KineticRegistry", version = "1", the chain id, and the registry address. The device does not hash the ticket itself: it asks the registry for hashClaim(device, owner, nonce, deadline) and signs that digest, so the device and the contract can never disagree on the encoding.

Claiming

claim is one owner transaction that does four things atomically:
1

Mint

The registry calls register(agentURI) on the Identity Registry. ERC-8004 always mints to the caller, so the NFT lands on the registry for a moment.
2

Transfer

The registry immediately transfers the NFT to msg.sender, the owner. The registry only accepts the NFT from the Identity Registry during this call.
3

Bind

The registry verifies the claim ticket, records the device as bound to the agent, and snapshots the current owner as boundOwner[agentId].
4

Initialize the vault

The registry calls DeviceVault.bindLimits(agentId, perTxCap, dailyCap) with the caps from the claim link. A first binding starts unpaused.
The claim reverts if the device is the owner (DeviceIsOwner), if the device or agent is already bound (AlreadyBound), if the ticket is expired, too far out, or signed by the wrong key, or if the registry has no vault wired yet (VaultUnset).
After claim, the owner also calls setApprovalForAll(KineticAttestor, true) on the Identity Registry. The registry cannot do this for the owner, because it only holds the NFT for an instant inside claim. Without that approval, attestations revert with NotOperator. See Attestations.

The binding rules

The registry enforces a strict one-to-one relationship.
  • One agent has at most one active device.
  • One device key is bound to at most one agent.
  • The device key is never the owner. claim, link, and rotate all reject a device equal to the caller.
  • The registry never approves the device key as an operator on the NFT, and the device key never holds ERC-721 rights over its own identity.

Active device and owner changes

activeDevice(agentId) is the function every other contract calls before letting a device spend or attest. It returns the bound device, and it reverts in two cases: That second check is what makes a machine safely transferable. The moment the NFT moves, the old device can no longer pay or attest, even before anyone cleans up. Anyone can then call releaseTransferred(agentId) to clear the old binding and pause the vault, and the new owner can link a device to themselves.

Reading identity from the device

The device never trusts a local copy. On every operation that needs identity, the runtime reads the chain:
  1. deviceToAgent(deviceAddress) returns (agentId, bound). Agent ids can be zero, so bound is the real flag.
  2. If bound, it reads ownerOfAgent(agentId) and the vault limits.
The monad_identity tool returns exactly this report, either unclaimed with the device address, or claimed with the agent, owner, device, caps, and pause state.

Lifecycle operations

Link

Bind a new device to an agent the caller already owns. Used after a revoke, or after a transfer release.

Rotate

Replace the device key in place. The new key signs a claim ticket naming the owner.

Revoke

Drop the device key and pause the vault. The NFT stays with the owner.

Release

Clear a device after the NFT moved. Anyone can call it.
The operator guide for each of these is Ownership. The function signatures and events are in the KineticRegistry reference.