> 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/guides/claim-issuer/29.-bring-an-eas-attestation-in-as-a-claim.md).

# 29. Bring an EAS attestation in as a claim

An investor that an attester has already verified on the Ethereum Attestation Service (EAS) does not need a second credential. The attestation is brought in as a claim: a record on the investor's ONCHAINID that points to the attestation and names the `EASClaimIssuer` adapter as its issuer. The Identity Owner adds the record once the attester has attested. From then on, every asset that trusts the adapter for the topic counts it, and the adapter reads the attestation from EAS at every eligibility check.

## At a glance

|                   |                                                                                                                                                                                                                                                                                                                                                    |
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Triggered by**  | Identity Owner, after the attester has attested                                                                                                                                                                                                                                                                                                    |
| **Actors**        | Attester, Investor, Identity Owner, Platform, Issuer, Network governance                                                                                                                                                                                                                                                                           |
| **Contracts**     | EAS, `EASClaimIssuer`, the ONCHAINID of the Investor, `ERC734Validator`, `IdentityFactory` (read only), `TREXRegistry` (read only, for the effect)                                                                                                                                                                                                 |
| **Preconditions** | The Investor has an ONCHAINID (see [02](/guides/identity/02.-deploy-an-onchainid.md)); an `EASClaimIssuer` is deployed for the EAS contract of the chain; in the adapter, the claim topic is bound to an EAS schema and the attester is accepted for that topic; the Identity Owner controls a `CLAIM_SIGNER` or `CLAIM_ADDER` key of the identity |
| **Result**        | The Investor's identity holds a claim whose issuer is the adapter and which points to the attestation. The claim is valid for as long as the attestation is                                                                                                                                                                                        |

## Actors and roles

| Actor              | Role in this flow                                                                                                               | What they hold                                        |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- |
| Attester           | Verifies the Investor off-chain and attests on EAS. It plays the part of a Claim Issuer, through the adapter.                   | An address accepted by the adapter for the topic      |
| Investor           | The subject of the attestation.                                                                                                 | An ONCHAINID                                          |
| Identity Owner     | The Investor in its capacity as controller of the identity. Adds the claim record.                                              | A `CLAIM_SIGNER` or `CLAIM_ADDER` key on its identity |
| Platform           | Reads the attestation, builds the record and prepares the call.                                                                 | Whatever keys the Identity Owner has authorized       |
| Issuer             | Decides whether its asset trusts the adapter for the topic. Does not transact in this flow.                                     | `OWNER` in the asset's domain                         |
| Network governance | Administers the adapter: which schema stands for which topic, and which attesters are accepted. Does not transact in this flow. | The role that administers the adapter                 |

## Sequence

```mermaid
sequenceDiagram
    participant Attester
    participant EAS
    participant Platform
    participant Owner as Identity Owner
    participant Identity as Investor ONCHAINID
    participant Validator as ERC734Validator
    participant Adapter as EASClaimIssuer
    participant Registry as TREXRegistry

    Attester->>EAS: attest, under the schema of the topic
    EAS-->>Attester: attestation UID
    Platform->>EAS: getAttestation(uid) (read)
    Platform->>Validator: getMetadataHash(scheme, uri) (read)
    Platform->>Adapter: getClaimStatus(identity, topic, signature, data) (read)
    Platform->>Owner: record ready, submit
    Owner->>Identity: addClaim(topic, scheme, adapter, signature, data, uri)
    Identity->>Validator: the identity's claim registry handles the call
    Validator->>Adapter: isClaimValid(identity, topic, signature, data)
    Adapter->>EAS: getAttestation(uid)
    Adapter-->>Validator: true
    Validator-->>Platform: ClaimAdded
    Platform->>Registry: isVerified(address) (read)
```

## Step by step

### Step 1. Attest on EAS

**Who:** Attester

**Call:** `attest` on the EAS contract of the chain. EAS is not part of the protocol

**Before the call:** The Attester has verified the Investor under its own process. It knows the schema that the adapter binds to the topic: `EASClaimIssuer.getSchemaForTopic(topic)`.

**What happens:** The Attester attests under that schema, with the Investor's ONCHAINID as recipient, or a wallet linked to it. EAS records the attestation and returns its UID. The attestation carries its time, its expiration time if it has one, and its data.

**What changes:** The attestation exists on EAS. Nothing changes in the protocol.

### Step 2. Build the claim record

**Who:** Platform, on behalf of the Identity Owner

**Call:** Off-chain, using read calls

**Before the call:** The Platform has the UID of the attestation.

**What happens:** The Platform reads the attestation with `getAttestation(uid)` on EAS and builds a record that mirrors it.

| Field               | Value                                                                                                                        |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `topic`             | The claim topic the attestation stands for.                                                                                  |
| `scheme`, `uri`     | How the claim is to be read, and where supporting material is.                                                               |
| `issuer`            | The address of the `EASClaimIssuer`.                                                                                         |
| `signature`         | The UID of the attestation, as 32 bytes.                                                                                     |
| `data.issuedAt`     | The time of the attestation.                                                                                                 |
| `data.validUntil`   | The expiration time of the attestation. Zero when it has none.                                                               |
| `data.metadataHash` | `getMetadataHash(scheme, uri)`, read on the `ERC734Validator`, the module whose address `Identity.registryModule()` returns. |
| `data.payload`      | The data of the attestation.                                                                                                 |

It then reads `EASClaimIssuer.getClaimStatus(identity, topic, signature, data)`, which must return `Valid`.

**What changes:** Nothing on-chain.

### Step 3. Add the claim record to the identity

**Who:** Identity Owner (`CLAIM_SIGNER` or `CLAIM_ADDER` key of the Investor's identity)

**Call:** `addClaim(topic, scheme, issuer, signature, data, uri)`, called on the Investor's ONCHAINID, with the adapter as `issuer`

**Before the call:** Step 2 returned `Valid`. The call is made directly on the identity by the key holder.

**What the contract checks:**

1. The caller holds `CLAIM_SIGNER` or `CLAIM_ADDER` on the identity. A `MANAGEMENT` key satisfies any purpose. Otherwise the call reverts with `SenderDoesNotHaveClaimSignerKey`.
2. The topic is not zero. Otherwise `InvalidClaimTopic`.
3. The signature, the payload and the URI are within their maximum lengths. Otherwise `ClaimSignatureTooLong`, `ClaimPayloadTooLong` or `ClaimUriTooLong`.
4. `data.metadataHash` matches the scheme and the URI. Otherwise `ClaimMetadataMismatch`.
5. The adapter answers that the claim is valid for this identity. Otherwise `InvalidClaim`. The adapter requires all of the following:
   * the topic is bound to a schema;
   * the signature is a 32-byte UID, and an attestation exists for it on EAS;
   * the attestation uses the schema bound to the topic, and its attester is accepted for the topic;
   * the record mirrors the attestation: same time, same expiration time, same data;
   * the attestation is not revoked and has not expired;
   * the recipient of the attestation is the identity itself, created by the `IdentityFactory`, or a wallet linked to the identity.

**What changes:** The claim is stored on the identity under `claimId = keccak256(abi.encode(issuer, topic))`. The `ERC734Validator` emits `ClaimAdded`, or `ClaimChanged` when the identity already held a claim from the adapter for this topic. Nothing is stored on the adapter.

### Step 4. Confirm the effect

**Who:** Platform

**Call:** Off-chain, using read calls

**Before the call:** Step 3 is confirmed.

**What happens:** For each asset the Investor wants to hold, the Platform reads `TREXRegistry.isVerified(address)` for the Investor's addresses. The result is true when the Issuer of the asset trusts the adapter for the topic (see [04](/guides/issuer/04.-add-a-trusted-claim-issuer.md)) and the other required topics of the asset are satisfied.

**What changes:** Nothing on-chain.

## State after the flow

* `getClaim(claimId)` on the Investor's identity returns the record, with the adapter as issuer and the UID as signature.
* `EASClaimIssuer.isClaimValid(identity, topic, signature, data)` returns true, for as long as the attestation is neither revoked nor expired and the adapter keeps the schema and the attester for the topic.
* For every asset that trusts the adapter for the topic, the claim satisfies the topic for every address of the Investor's identity.
* The adapter holds no record of the claim. It answers from EAS at every call.
* An indexer has seen `ClaimAdded` or `ClaimChanged` on the `ERC734Validator`.

## Failure modes

| Symptom                                                                                     | Cause                                                                                                                                                                                                                                                 | Fix                                                                                                                                       |
| ------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `getClaimStatus` returns `NotIssued`                                                        | The topic is not bound to a schema, the attestation uses another schema, the attester is not accepted for the topic, the record does not mirror the attestation, or the recipient is neither the identity nor a wallet linked to it (step 3, check 5) | Compare the record with `getAttestation(uid)`. Read `getSchemaForTopic(topic)` and `getIsAttesterAllowed(topic, attester)` on the adapter |
| `getClaimStatus` returns `BadSignature`                                                     | The signature field is not a 32-byte UID (step 3, check 5)                                                                                                                                                                                            | Pass the UID as `abi.encodePacked(uid)`                                                                                                   |
| `getClaimStatus` returns `Revoked` or `Expired`                                             | The attester revoked the attestation on EAS, or the attestation reached its expiration time (step 3, check 5)                                                                                                                                         | The Attester attests again. Use the new UID                                                                                               |
| `addClaim` reverts with `SenderDoesNotHaveClaimSignerKey`                                   | The caller holds neither `CLAIM_SIGNER` nor `CLAIM_ADDER` on the identity (step 3, check 1)                                                                                                                                                           | Submit with a claim key of the identity                                                                                                   |
| `addClaim` reverts with `InvalidClaimTopic`                                                 | The topic is zero (step 3, check 2)                                                                                                                                                                                                                   | Use the claim topic the schema is bound to                                                                                                |
| `addClaim` reverts with `ClaimSignatureTooLong`, `ClaimPayloadTooLong` or `ClaimUriTooLong` | A field exceeds its maximum length (step 3, check 3)                                                                                                                                                                                                  | An attestation whose data exceeds the maximum payload cannot be brought in as a claim                                                     |
| `addClaim` reverts with `ClaimMetadataMismatch`                                             | `data.metadataHash` was computed for another scheme or URI (step 3, check 4)                                                                                                                                                                          | Read `ERC734Validator.getMetadataHash(scheme, uri)` again with the values submitted                                                       |
| `addClaim` reverts with `InvalidClaim`                                                      | The adapter does not answer `Valid` (step 3, check 5)                                                                                                                                                                                                 | Read `getClaimStatus` for the reason, as in step 2                                                                                        |
| The call is refused when sent as a user operation                                           | `addClaim` requires a direct call from the key holder                                                                                                                                                                                                 | Call the identity directly                                                                                                                |
| `addClaimTo` on the adapter reverts with `EASNotSupported`                                  | The adapter cannot add a claim to an identity                                                                                                                                                                                                         | The Identity Owner adds the record, as in step 3                                                                                          |
| The claim is on the identity and the Investor is not eligible for an asset                  | The Issuer of that asset does not trust the adapter for the topic, or another required topic is not satisfied                                                                                                                                         | The Issuer decides: [04](/guides/issuer/04.-add-a-trusted-claim-issuer.md)                                                                |
| The claim was valid and no longer is                                                        | The attester revoked the attestation, the attestation expired, or the adapter no longer accepts the attester or the schema                                                                                                                            | Nothing to repair on the identity. A new attestation is brought in with this flow                                                         |

## Common misunderstandings

> **Wrong:** "The adapter issues the claim."
>
> **Right:** The adapter adds nothing to any identity and stores nothing. The Identity Owner adds the record. The adapter answers one question, at every check: is the attestation behind this record valid for this identity, now.

> **Wrong:** "Once the record is on the identity, the investor stays eligible."
>
> **Right:** Validity is read from EAS at every eligibility check. When the attester revokes the attestation, or when it expires, the claim stops counting from the next check, with no transaction in the protocol.

> **Wrong:** "The record can describe the attestation in its own words."
>
> **Right:** The record mirrors the attestation: its time, its expiration time and its data. The adapter refuses a record that differs, so what an identity stores is what the attester signed.

> **Wrong:** "An attestation made to a wallet is lost when the wallet is revoked."
>
> **Right:** The adapter accepts an attestation made to a wallet linked to the identity, whether the link is active or revoked. The attestation is a fact about the investor. The revoked wallet is refused as a recipient by every asset, and the identity keeps its credential.

## Integration notes

* An Attester needs no ONCHAINID and no key on the Investor's identity. It attests on EAS as it already does. What makes its attestations count is the adapter's configuration, and each Issuer's decision to trust the adapter.
* `EASClaimIssuer.getAttestationData(signature)` is a raw read. It returns the data of an attestation even when the attestation is revoked, expired or from an attester the adapter does not accept. Decide on `isClaimValid` or `getClaimStatus`, never on the data alone.
* An identity holds one claim per issuer and topic. Bringing in a new attestation for the same topic through the same adapter replaces the record, and emits `ClaimChanged`.
* To renew, the Attester attests again and the Identity Owner repeats steps 2 and 3 with the new UID. A revoked attestation cannot be brought in again: the adapter reads the revocation.
* The Identity Owner removes the record with `removeClaim(claimId)` on its identity, with a `CLAIM_SIGNER` key: a `CLAIM_ADDER` key adds claims and cannot remove them. Removal is optional: a record whose attestation is revoked or expired no longer counts.
* The adapter reads attestations that exist on-chain, on its own chain. It does not read off-chain attestations or attestations made on another chain.
* Before relying on an adapter, an Issuer reads which schema it binds to each topic and which attesters it accepts, and follows `SchemaForTopicSet` and `AttesterSet` on the adapter. An attester added there widens what the asset accepts.

## Related flows

* [05 Issue a claim to an investor](/guides/claim-issuer/05.-issue-a-claim-to-an-investor.md) : a claim signed by a Claim Issuer identity
* [19 Revoke a claim](/guides/claim-issuer/19.-revoke-a-claim.md) : revocation by a Claim Issuer identity. For an attestation, revocation happens on EAS
* [04 Add a trusted Claim Issuer](/guides/issuer/04.-add-a-trusted-claim-issuer.md) : how an Issuer trusts the adapter for a topic
* [20 Remove a trusted Claim Issuer](/guides/issuer/20.-remove-a-trusted-claim-issuer.md) : how an Issuer stops trusting it
* [External attestations](/identity-onchainid/external-attestations.md) : the adapter model and its trust assumptions


---

# 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/guides/claim-issuer/29.-bring-an-eas-attestation-in-as-a-claim.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.
