IAgent.getAgentIds
getAgentIds(
address wallet,
PageRequest pageRequest
) external view returns (uint256[] agentIds, PageResponse pageResponse) Paginated reverse lookup: returns the agent IDs registered to wallet. The Agent precompile exposes this method because walking IdentityRegistry storage from inside a contract is too expensive — the precompile reads from a chain-side index that is kept in sync. For everything else (register, attest, revoke, metadata), call the ERC-8004 IdentityRegistry preinstall at 0x8004000000000000000000000000000000000001 directly.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
wallet | address | ✓ | The wallet address to look up. If a non-address value is ABI-decoded into this slot the call reverts with InvalidAddress(string bad) carrying a best-effort debug string of the offending value. |
pageRequest | tuple | ✓ | Standard pagination tuple (bytes key, uint64 offset, uint64 limit, bool countTotal, bool reverse). Malformed tuples revert with InvalidPageRequest(string method, uint256 index, string value). |
Returns
tuple Returns (uint256[] agentIds, PageResponse pageResponse). pageResponse.nextKey is empty when the last page is reached.
Errors
| Code | Name | Description |
|---|---|---|
InvalidNumberOfArgs | InvalidNumberOfArgs | Reverts when the ABI-decoded argument count differs from the two arguments this method expects. Encoded as InvalidNumberOfArgs(uint256 expected, uint256 got). |
InvalidAddress | InvalidAddress | Reverts when the first argument does not ABI-decode into an address. Encoded as InvalidAddress(string bad) where bad is a best-effort debug rendering of the offending value. |
InvalidPageRequest | InvalidPageRequest | Reverts when the second argument does not ABI-decode into the expected PageRequest tuple. Encoded as InvalidPageRequest(string method, uint256 index, string value). |
QueryFailed | QueryFailed | Reverts when the underlying chain-side index lookup fails. Encoded as QueryFailed(string queryMethod, string reason). |
UnknownMethod | UnknownMethod | Reverts when calldata does not match a known method selector on this precompile. Encoded as UnknownMethod(string methodName). |
Examples
Paginate all agent IDs for a wallet
Iterate until nextKey is empty to collect the full list.
import { createPublicClient, http } from "viem";
const AGENT_PRECOMPILE = "0x100000000000000000000000000000000000000A" as const;
const agentAbi = [{
type: "function", name: "getAgentIds", stateMutability: "view",
inputs: [
{ name: "wallet", type: "address" },
{ name: "pageRequest", type: "tuple", components: [
{ name: "key", type: "bytes" },
{ name: "offset", type: "uint64" },
{ name: "limit", type: "uint64" },
{ name: "countTotal", type: "bool" },
{ name: "reverse", type: "bool" },
]},
],
outputs: [
{ name: "agentIds", type: "uint256[]" },
{ name: "pageResponse", type: "tuple", components: [
{ name: "nextKey", type: "bytes" },
{ name: "total", type: "uint64" },
]},
],
}] as const;
const publicClient = createPublicClient({ transport: http("https://rpc-testnet.maroo.io") });
// TODO: replace with the real owner wallet before production.
const wallet = "0x8F3ac2B1d9E74c05A6B18FE27Dc4913e5A0F7b62";
let key: `0x${string}` = "0x";
const allIds: bigint[] = [];
do {
const [ids, page] = await publicClient.readContract({
address: AGENT_PRECOMPILE,
abi: agentAbi,
functionName: "getAgentIds",
args: [wallet, { key, offset: 0n, limit: 100n, countTotal: false, reverse: false }],
});
allIds.push(...ids);
key = page.nextKey as `0x${string}`;
} while (key !== "0x"); Decoding shared IPrecompile errors
The error shapes changed: the old bespoke InvalidArgsLength(method, got, want) is gone, and InvalidAddress / InvalidPageRequest now use the shared IPrecompile signatures.
import { decodeErrorResult } from "viem";
const iPrecompileErrorsAbi = [
{ type: "error", name: "InvalidNumberOfArgs",
inputs: [{ name: "expected", type: "uint256" }, { name: "got", type: "uint256" }] },
{ type: "error", name: "InvalidAddress", inputs: [{ name: "bad", type: "string" }] },
{ type: "error", name: "InvalidPageRequest",
inputs: [
{ name: "method", type: "string" },
{ name: "index", type: "uint256" },
{ name: "value", type: "string" },
] },
{ type: "error", name: "QueryFailed",
inputs: [{ name: "queryMethod", type: "string" }, { name: "reason", type: "string" }] },
] as const;
try {
await publicClient.readContract({
address: AGENT_PRECOMPILE,
abi: agentAbi,
functionName: "getAgentIds",
args: [wallet, { key: "0x", offset: 0n, limit: 100n, countTotal: false, reverse: false }],
});
} catch (err: any) {
if (err?.data) {
const decoded = decodeErrorResult({ abi: iPrecompileErrorsAbi, data: err.data });
console.error("getAgentIds reverted:", decoded.errorName, decoded.args);
} else {
throw err;
}
}