EAS Precompile

component identity

Returns the canonical EAS module addresses (SchemaRegistry, EAS, Indexer). Failures share the IPrecompile typed-error surface, with a single plain-string revert for uninitialized state.

The EAS precompile at 0x1000000000000000000000000000000000000009 is a thin discovery surface. It exposes a single view method — getParams() — that returns the canonical schemaRegistry, eas, and indexer addresses on this chain. The actual attestation API (issue, query, revoke) lives on the EAS contract preinstall, not on this precompile. As of the latest interface, IEas inherits IPrecompile, so argument-shape failures surface as typed errors from the shared set.

The Solidity interface

Straight from IEas.sol. IEas inherits IPrecompile, so it does not declare its own error types.
import {IPrecompile} from "../common/interfaces/IPrecompile.sol";

address constant EAS_PRECOMPILED_ADDRESS =
    0x1000000000000000000000000000000000000009;

struct EasParams {
    address schemaRegistry;
    address eas;
    address indexer;
}

interface IEas is IPrecompile {
    function getParams() external view returns (EasParams memory params);
}

Why the precompile exists

The EAS contract, its schema registry, and the indexer are all preinstalls deployed at genesis. Their addresses are stable, but they are not the same across every chain the toolchain targets, so a dApp that hard-codes them ships broken. getParams() gives you the trio at runtime, letting the same code path work on testnet and mainnet without a switch.

Error surface — shared IPrecompile plus one plain-string revert

Argument-shape and dispatch failures surface as typed errors from the shared set — most notably InvalidNumberOfArgs(uint256 expected, uint256 got) if calldata carries extra ABI-encoded values, and UnknownMethod(string methodName) for an unrecognized selector. Underlying module-lookup failures surface as QueryFailed(string queryMethod, string reason). There is one exception: if the precompile's easKeeper reference has not been wired at startup, the call reverts with the plain UTF-8 string "eas keeper is not initialized" rather than a typed error, so decode it as a string when typed decoding fails. See precompile-shared-errors for the full IPrecompile catalog.
import { decodeErrorResult, hexToString } from "viem";

const iPrecompileErrorsAbi = [
  { type: "error", name: "InvalidNumberOfArgs",
    inputs: [{ name: "expected", type: "uint256" }, { name: "got", type: "uint256" }] },
  { type: "error", name: "UnknownMethod", inputs: [{ name: "methodName", type: "string" }] },
  { type: "error", name: "QueryFailed",
    inputs: [{ name: "queryMethod", type: "string" }, { name: "reason", type: "string" }] },
] as const;

function decodeEasRevert(errData: `0x${string}`) {
  try {
    return decodeErrorResult({ abi: iPrecompileErrorsAbi, data: errData });
  } catch {
    // Plain-string revert (e.g. "eas keeper is not initialized").
    return { errorName: hexToString(errData), args: [] };
  }
}

Usage — resolve, then call the EAS contract directly

Call getParams() once at startup and cache the addresses. Every other operation — schema registration, attestation issuance, attestation lookup, revocation — talks to the EAS contract or SchemaRegistry preinstall directly using their standard ABIs.
import { createPublicClient, http } from "viem";

const EAS_PRECOMPILE = "0x1000000000000000000000000000000000000009" as const;
const easPrecompileAbi = [{
  type: "function", name: "getParams", stateMutability: "view",
  inputs: [],
  outputs: [{ type: "tuple", components: [
    { name: "schemaRegistry", type: "address" },
    { name: "eas",            type: "address" },
    { name: "indexer",        type: "address" },
  ]}],
}] as const;

const publicClient = createPublicClient({ transport: http("https://rpc-testnet.maroo.io") });
const { schemaRegistry, eas, indexer } = await publicClient.readContract({
  address: EAS_PRECOMPILE,
  abi: easPrecompileAbi,
  functionName: "getParams",
});

// Feed `eas`, `indexer`, `schemaRegistry` into @ethereum-attestation-service/eas-sdk
// or your ABI of choice for the actual attestation flow.
console.log({ schemaRegistry, eas, indexer });

See Also

ESC
Type to search