Agent Precompile
Returns ERC-8004 IdentityRegistry / ReputationRegistry addresses + indexed getAgentIds(wallet) lookup. Other agent ops go directly to IdentityRegistry.
The Agent precompile at 0x100000000000000000000000000000000000000A is a thin discovery + indexing surface. It exposes two view methods: getParams() (returns the addresses of the ERC-8004 IdentityRegistry and ReputationRegistry preinstalls on this chain) and getAgentIds(wallet, pageRequest) (paginated list of agent IDs registered by a given wallet — backed by an x/agent chain-side index for cheap lookup). All actual agent state operations — registration, attestation, revocation, metadata reads — happen on the ERC-8004 IdentityRegistry preinstall at the address returned by getParams().
The IAgent interface (full surface)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {PageRequest, PageResponse} from "cosmos-evm-contracts/precompiles/common/Types.sol";
interface IAgent {
error InvalidArgsLength(string method, uint256 got, uint256 want);
error InvalidAddress(string method, uint256 index, string value);
error InvalidPageRequest(string method, uint256 index, string value);
struct Params {
address identityRegistry;
address reputationRegistry;
}
function getParams() external view returns (Params memory);
function getAgentIds(address wallet, PageRequest calldata pageRequest)
external
view
returns (uint256[] memory agentIds, PageResponse calldata pageResponse);
} Two methods — that's the entire surface. The Agent precompile is intentionally minimal because the rich agent surface (lifecycle, metadata, delegation) lives in the ERC-8004 standard contracts.
Why this split (precompile vs registry)
ERC-8004 IdentityRegistry is a standard Solidity contract that handles the agent lifecycle:
1. Per-wallet enumeration — "list all agent IDs that wallet X owns". Walking IdentityRegistry storage from inside a contract is expensive; the precompile reads from a chain-side index that's kept in sync, so the lookup is cheap and supports pagination.
2. Network-portable discovery —
Writes and most reads still go through the IdentityRegistry contract — the precompile is a query/discovery helper, not an authority.
register, attest, revoke, get metadata, etc. The Maroo precompile complements it with two things the standard contract can't cheaply do at the EVM layer:1. Per-wallet enumeration — "list all agent IDs that wallet X owns". Walking IdentityRegistry storage from inside a contract is expensive; the precompile reads from a chain-side index that's kept in sync, so the lookup is cheap and supports pagination.
2. Network-portable discovery —
getParams() lets a contract resolve which IdentityRegistry / ReputationRegistry to call without hard-coded addresses. Useful for code that runs on both testnet and mainnet without modification.Writes and most reads still go through the IdentityRegistry contract — the precompile is a query/discovery helper, not an authority.
Calling pattern
import {PageRequest, PageResponse} from "cosmos-evm-contracts/precompiles/common/Types.sol";
interface IAgent {
struct Params { address identityRegistry; address reputationRegistry; }
function getParams() external view returns (Params memory);
function getAgentIds(address wallet, PageRequest calldata pageRequest)
external view
returns (uint256[] memory agentIds, PageResponse calldata pageResponse);
}
IAgent constant AGENT = IAgent(0x100000000000000000000000000000000000000A);
contract MyAgentDashboard {
function listAgents(address wallet) external view returns (uint256[] memory) {
// first page (no pagination key, default limit)
PageRequest memory pr;
(uint256[] memory ids, ) = AGENT.getAgentIds(wallet, pr);
return ids;
}
function identityRegistry() external view returns (address) {
return AGENT.getParams().identityRegistry;
}
} For agent registration / metadata / attestation, call IdentityRegistry directly (its address is returned by
getParams(), or hard-coded as 0x8004000000000000000000000000000000000001 on testnet). See erc-8004-identity-registry.V1 scope
Per the Maroo litepaper, V1 actively uses Identity Registry only. ReputationRegistry exists at
0x8004000000000000000000000000000000000002 (preinstalled) but is reserved for V2+ usage; getParams().reputationRegistry returns its address regardless of activation status. ValidationRegistry from the ERC-8004 standard is not present in V1.