EAS Precompile
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
Calldata that does not match a method — an unknown selector, for example from a stale ABI — reverts with
ABISetupFailed(string reason) from the shared set (reason no method with id: 0x…), not UnknownMethod. Bytes after the selector are ignored, so extra ABI-encoded values do not produce InvalidNumberOfArgs. Underlying module-lookup failures surface as QueryFailed(string queryMethod, string reason). One failure has no typed error: if the precompile's easKeeper reference was not wired at startup, the call reverts with the plain reason "eas keeper is not initialized", ABI-encoded as Solidity's Error(string), so decodeErrorResult returns it as errorName: "Error" with the reason in args[0]. See precompile-shared-errors for the full IPrecompile catalog.import { decodeErrorResult } from "viem";
const iPrecompileErrorsAbi = [
{ type: "error", name: "InvalidNumberOfArgs",
inputs: [{ name: "expected", type: "uint256" }, { name: "got", type: "uint256" }] },
{ type: "error", name: "ABISetupFailed", inputs: [{ name: "reason", type: "string" }] },
{ type: "error", name: "QueryFailed",
inputs: [{ name: "queryMethod", type: "string" }, { name: "reason", type: "string" }] },
] as const;
// decodeErrorResult also knows Solidity's Error(string), so a plain reason
// (e.g. "eas keeper is not initialized") decodes as errorName "Error".
// It throws for a revert this ABI does not describe.
function decodeEasRevert(errData: `0x${string}`) {
return decodeErrorResult({ abi: iPrecompileErrorsAbi, data: errData });
} 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 });