> For the complete documentation index, see [llms.txt](https://docs.t-rex.network/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.t-rex.network/reference/identity-suite/erc734validator.md).

# ERC734Validator

`ERC734Validator` is the registry module of ONCHAINID. One deployment holds the keys and the claims of every identity, validates the signatures of user operations, and answers for the claims an identity issued. An identity reaches it through its own functions and its fallback. The concepts are in [Claims: issuance, validity, revocation](/identity-onchainid/claims-issuance-validity-revocation.md).

### At a glance

|                  |                                                                                                                                     |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| **Source**       | `contracts/modules/validators/ERC734Validator.sol`                                                                                  |
| **Module types** | Validator, executor and fallback handler (ERC-7579)                                                                                 |
| **Deployed as**  | One contract per network, built with the `IdentityFactory` and the `ReputationRegistry`. Its address is `Identity.registryModule()` |
| **State**        | Per identity: keys, claims and revoked digests. It persists if the module is uninstalled                                            |
| **Limits**       | 2,048 bytes each for the signature, the payload and the URI of a claim                                                              |

Functions that take no account act on the caller: called through an identity, they act on that identity. The same reads exist with an explicit `account` argument, for a direct call to the module.

### Keys

| Function                                                                                             | Called by                                      | Behavior                                                                                                                                                                                                     |
| ---------------------------------------------------------------------------------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `addKey(signerData, clientData, purpose, keyType, caller)`                                           | An identity, from `addKey` or `addKeyWithData` | Registers a purpose for `keccak256(signerData)`. Reverts with `InvalidPurpose`, `KeyAlreadyRegistered`, `KeyTypeMismatch`, `InvalidSignerLength`, `ModuleCannotBeKey`, `ClientDataTooLong`. Emits `KeyAdded` |
| `removeKey(keyHash, purpose, caller)`                                                                | An identity, from `removeKey`                  | Reverts with `KeyDoesNotHavePurpose`, `CannotRemoveLastManagementKey`. Emits `KeyRemoved`                                                                                                                    |
| `keyHasPurpose(account, keyHash, purpose)`                                                           | Anyone, read                                   | True for the purpose, or for `MANAGEMENT`                                                                                                                                                                    |
| `getKey(account, keyHash)`, `getKeyPurposes(account, keyHash)`, `getKeysByPurpose(account, purpose)` | Anyone, read                                   | The record of a key, its purposes, the keys of a purpose. The last two have a form with `start` and `end`                                                                                                    |
| `getKeyData(account, keyHash)`                                                                       | Anyone, read                                   | The `signerData` and `clientData` stored for a key                                                                                                                                                           |
| `onInstall(data)`                                                                                    | An identity, at creation                       | Registers the first `MANAGEMENT` key                                                                                                                                                                         |

### Claims held by an identity

| Function                                                                        | Access                                                                                                                                                             | Reverts with                                                                                                                                                                                                                                                                                                                |
| ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `addClaim(_topic, _scheme, _issuer, _signature, _data, _uri)`                   | A key that holds `CLAIM_SIGNER` or `CLAIM_ADDER` on the identity, calling it directly. Or the issuer's identity, with a claim key on the identity or with standing | `SenderDoesNotHaveClaimSignerKey`, `IdentityNotClaimIssuerType`, `ReputationBelowClaimAddThreshold`, `InvalidClaimTopic`, `ClaimSignatureTooLong`, `ClaimPayloadTooLong`, `ClaimUriTooLong`, `ClaimMetadataMismatch`, `InvalidClaim`. Returns the `claimId`. Emits `ClaimAdded`, or `ClaimChanged` when it replaces a claim |
| `removeClaim(_claimId)`                                                         | A key that holds `CLAIM_SIGNER` on the identity. Or the issuer of the claim, with standing                                                                         | `ClaimNotRegistered`, `SenderDoesNotHaveClaimSignerKey`, `IdentityNotClaimIssuerType`, `ReputationBelowClaimAddThreshold`. Marks the digest of the claim revoked on the issuer. Emits `ClaimRemoved`                                                                                                                        |
| `getClaim(_claimId)`                                                            | Anyone, read                                                                                                                                                       | `topic`, `scheme`, `issuer`, `signature`, `data`, `uri`                                                                                                                                                                                                                                                                     |
| `getClaimIdsByTopic(_topic)`, `getClaimIdsByTopicPaginated(_topic, start, end)` | Anyone, read                                                                                                                                                       | The claims of a topic. The paginated form is on the module only                                                                                                                                                                                                                                                             |

`claimId` is `keccak256(abi.encode(issuer, topic))`: an identity holds one claim per issuer and topic. Standing means the issuer's identity is of type `CLAIM_ISSUER` in the factory and its reputation is at least the claim-add threshold.

### Functions of a Claim Issuer

| Function                                                          | Access                                                           | Behavior                                                                                                                                                                  |
| ----------------------------------------------------------------- | ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `addClaimTo(_topic, _scheme, _signature, _data, _uri, _identity)` | A `MANAGEMENT` key of the issuer's identity, calling it directly | Checks the claim, then calls `addClaim` on `_identity`. Reverts with `SenderDoesNotHaveManagementKey`, `InvalidClaim`, and the errors of `addClaim`. Emits `ClaimAddedTo` |
| `revokeClaimByDigest(digest)`                                     | A `MANAGEMENT` key of the issuer's identity, calling it directly | Reverts with `SenderDoesNotHaveManagementKey`, `ClaimAlreadyRevoked`. Emits `ClaimRevoked`. A revoked digest stays revoked                                                |
| `isDigestRevoked(digest)`                                         | Anyone, read                                                     | Whether the calling issuer revoked the digest                                                                                                                             |
| `isClaimValid(_identity, claimTopic, sig, data)`                  | Anyone, read                                                     | True when the status of the claim is `Valid` for the calling issuer. The `TREXRegistry` calls it on the issuer's identity at every eligibility check                      |
| `getClaimStatus(_identity, claimTopic, sig, data)`                | Anyone, read, on the module                                      | The status, with the caller as issuer. The identity does not route it: read it with an `eth_call` to the module, with `from` set to the issuer's identity                 |
| `getClaimHash(_identity, _topic, _data)`                          | Anyone, read                                                     | The ERC-712 digest a signer signs for a claim, in the domain of the calling issuer                                                                                        |
| `getMetadataHash(_scheme, _uri)`                                  | Anyone, read, on the module                                      | The `metadataHash` a claim must carry for a scheme and a URI                                                                                                              |

`ClaimStatus` has six values, in this order: `Valid`, `BadSignature`, `NotIssued`, `Revoked`, `NotYetValid`, `Expired`. How each is reached is in [Integrate as a Claim Issuer](/build/integrate-as-a-claim-issuer.md).

### Signature validation

| Function                                              | Behavior                                                                                                                                |
| ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `validateUserOp` (ERC-7579 validator)                 | Checks the signature of a user operation against a key of the account, and that the purpose of the key covers the call. Emits `KeyUsed` |
| `isValidSignatureWithSender(sender, hash, signature)` | ERC-1271 for the account: valid only for a key that holds `ACTION` or `MANAGEMENT`                                                      |
| `isModuleType(moduleTypeId)`                          | True for validator, executor and fallback                                                                                               |

### Events

| Event                                                                                                                                                                                                                                        | Emitted when                                            |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- |
| `KeyAdded(address indexed account, bytes32 indexed keyHash, uint256 indexed purpose, uint256 keyType, bytes signerData, bytes clientData, address caller)`                                                                                   | A key receives a purpose on the identity `account`      |
| `KeyRemoved(address indexed account, bytes32 indexed keyHash, uint256 indexed purpose, address caller)`                                                                                                                                      | A purpose is removed from a key                         |
| `KeyUsed(address indexed account, bytes32 indexed keyHash, bytes32 userOpHash)`                                                                                                                                                              | A user operation of `account` validates against the key |
| `ClaimAdded(address indexed identity, bytes32 claimId, uint256 indexed topic, uint256 scheme, address indexed issuer, bytes signature, Structs.ClaimData data, string uri, address caller)`, `ClaimChanged`, `ClaimRemoved` (same arguments) | A claim is added to `identity`, replaced, removed       |
| `ClaimRevoked(bytes32 indexed digest, address indexed issuer, address caller)`                                                                                                                                                               | An issuer revokes a digest                              |
| `ClaimAddedTo(address indexed identity, uint256 topic, bytes signature, Structs.ClaimData data, address caller)`                                                                                                                             | An issuer delivered a claim with `addClaimTo`           |

`Structs.ClaimData` is `(uint256 issuedAt, uint256 validUntil, bytes32 metadataHash, bytes payload)`.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.t-rex.network/reference/identity-suite/erc734validator.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
