{"version":3,"file":"access-control-BA74EeRO-DMXhJiUk.mjs","names":[],"sources":["../../adapter-evm-core/dist/access-control-BA74EeRO.mjs"],"sourcesContent":["import { t as createEvmPublicClient } from \"./public-client-DtJS2A20.mjs\";\nimport { t as isValidEvmAddress } from \"./validation--Y5v5XOf.mjs\";\nimport { i as resolveRpcUrl } from \"./rpc-BMyYpWRW.mjs\";\nimport { c as guardRuntimeCapability, n as asTypedEvmNetworkConfig } from \"./helpers-CYDHdjrw.mjs\";\nimport { i as resolveAccessControlIndexerUrl } from \"./configuration-DSvdNI95.mjs\";\nimport { logger, validateSnapshot } from \"@openzeppelin/ui-utils\";\nimport { ConfigurationInvalid, OperationFailed } from \"@openzeppelin/ui-types\";\n\n//#region src/access-control/abis.ts\n/** ABI for `owner() → address` */\nconst OWNER_ABI = [{\n\ttype: \"function\",\n\tname: \"owner\",\n\tinputs: [],\n\toutputs: [{\n\t\tname: \"\",\n\t\ttype: \"address\"\n\t}],\n\tstateMutability: \"view\"\n}];\n/** ABI for `transferOwnership(address newOwner)` */\nconst TRANSFER_OWNERSHIP_ABI = [{\n\ttype: \"function\",\n\tname: \"transferOwnership\",\n\tinputs: [{\n\t\tname: \"newOwner\",\n\t\ttype: \"address\"\n\t}],\n\toutputs: [],\n\tstateMutability: \"nonpayable\"\n}];\n/** ABI for `renounceOwnership()` */\nconst RENOUNCE_OWNERSHIP_ABI = [{\n\ttype: \"function\",\n\tname: \"renounceOwnership\",\n\tinputs: [],\n\toutputs: [],\n\tstateMutability: \"nonpayable\"\n}];\n/** ABI for `pendingOwner() → address` */\nconst PENDING_OWNER_ABI = [{\n\ttype: \"function\",\n\tname: \"pendingOwner\",\n\tinputs: [],\n\toutputs: [{\n\t\tname: \"\",\n\t\ttype: \"address\"\n\t}],\n\tstateMutability: \"view\"\n}];\n/** ABI for `acceptOwnership()` */\nconst ACCEPT_OWNERSHIP_ABI = [{\n\ttype: \"function\",\n\tname: \"acceptOwnership\",\n\tinputs: [],\n\toutputs: [],\n\tstateMutability: \"nonpayable\"\n}];\n/** ABI for `grantRole(bytes32 role, address account)` */\nconst GRANT_ROLE_ABI = [{\n\ttype: \"function\",\n\tname: \"grantRole\",\n\tinputs: [{\n\t\tname: \"role\",\n\t\ttype: \"bytes32\"\n\t}, {\n\t\tname: \"account\",\n\t\ttype: \"address\"\n\t}],\n\toutputs: [],\n\tstateMutability: \"nonpayable\"\n}];\n/** ABI for `revokeRole(bytes32 role, address account)` */\nconst REVOKE_ROLE_ABI = [{\n\ttype: \"function\",\n\tname: \"revokeRole\",\n\tinputs: [{\n\t\tname: \"role\",\n\t\ttype: \"bytes32\"\n\t}, {\n\t\tname: \"account\",\n\t\ttype: \"address\"\n\t}],\n\toutputs: [],\n\tstateMutability: \"nonpayable\"\n}];\n/** ABI for `renounceRole(bytes32 role, address callerConfirmation)` */\nconst RENOUNCE_ROLE_ABI = [{\n\ttype: \"function\",\n\tname: \"renounceRole\",\n\tinputs: [{\n\t\tname: \"role\",\n\t\ttype: \"bytes32\"\n\t}, {\n\t\tname: \"callerConfirmation\",\n\t\ttype: \"address\"\n\t}],\n\toutputs: [],\n\tstateMutability: \"nonpayable\"\n}];\n/** ABI for `getRoleMemberCount(bytes32 role) → uint256` */\nconst GET_ROLE_MEMBER_COUNT_ABI = [{\n\ttype: \"function\",\n\tname: \"getRoleMemberCount\",\n\tinputs: [{\n\t\tname: \"role\",\n\t\ttype: \"bytes32\"\n\t}],\n\toutputs: [{\n\t\tname: \"\",\n\t\ttype: \"uint256\"\n\t}],\n\tstateMutability: \"view\"\n}];\n/** ABI for `getRoleMember(bytes32 role, uint256 index) → address` */\nconst GET_ROLE_MEMBER_ABI = [{\n\ttype: \"function\",\n\tname: \"getRoleMember\",\n\tinputs: [{\n\t\tname: \"role\",\n\t\ttype: \"bytes32\"\n\t}, {\n\t\tname: \"index\",\n\t\ttype: \"uint256\"\n\t}],\n\toutputs: [{\n\t\tname: \"\",\n\t\ttype: \"address\"\n\t}],\n\tstateMutability: \"view\"\n}];\n/** ABI for `defaultAdmin() → address` */\nconst DEFAULT_ADMIN_ABI = [{\n\ttype: \"function\",\n\tname: \"defaultAdmin\",\n\tinputs: [],\n\toutputs: [{\n\t\tname: \"\",\n\t\ttype: \"address\"\n\t}],\n\tstateMutability: \"view\"\n}];\n/**\n* ABI for `pendingDefaultAdmin() → (address newAdmin, uint48 schedule)`\n*\n* Returns a tuple of the pending new admin address and the UNIX timestamp\n* (in seconds) at which the transfer can be accepted.\n*/\nconst PENDING_DEFAULT_ADMIN_ABI = [{\n\ttype: \"function\",\n\tname: \"pendingDefaultAdmin\",\n\tinputs: [],\n\toutputs: [{\n\t\tname: \"newAdmin\",\n\t\ttype: \"address\"\n\t}, {\n\t\tname: \"schedule\",\n\t\ttype: \"uint48\"\n\t}],\n\tstateMutability: \"view\"\n}];\n/** ABI for `defaultAdminDelay() → uint48` */\nconst DEFAULT_ADMIN_DELAY_ABI = [{\n\ttype: \"function\",\n\tname: \"defaultAdminDelay\",\n\tinputs: [],\n\toutputs: [{\n\t\tname: \"\",\n\t\ttype: \"uint48\"\n\t}],\n\tstateMutability: \"view\"\n}];\n/**\n* ABI for `pendingDefaultAdminDelay() → (uint48 newDelay, uint48 schedule)`\n*\n* Returns a tuple of the pending new admin delay (in seconds) and the UNIX\n* timestamp at which the delay change takes effect.  Returns (0, 0) when no\n* delay change is scheduled.\n*/\nconst PENDING_DEFAULT_ADMIN_DELAY_ABI = [{\n\ttype: \"function\",\n\tname: \"pendingDefaultAdminDelay\",\n\tinputs: [],\n\toutputs: [{\n\t\tname: \"newDelay\",\n\t\ttype: \"uint48\"\n\t}, {\n\t\tname: \"schedule\",\n\t\ttype: \"uint48\"\n\t}],\n\tstateMutability: \"view\"\n}];\n/** ABI for `beginDefaultAdminTransfer(address newAdmin)` */\nconst BEGIN_DEFAULT_ADMIN_TRANSFER_ABI = [{\n\ttype: \"function\",\n\tname: \"beginDefaultAdminTransfer\",\n\tinputs: [{\n\t\tname: \"newAdmin\",\n\t\ttype: \"address\"\n\t}],\n\toutputs: [],\n\tstateMutability: \"nonpayable\"\n}];\n/** ABI for `acceptDefaultAdminTransfer()` */\nconst ACCEPT_DEFAULT_ADMIN_TRANSFER_ABI = [{\n\ttype: \"function\",\n\tname: \"acceptDefaultAdminTransfer\",\n\tinputs: [],\n\toutputs: [],\n\tstateMutability: \"nonpayable\"\n}];\n/** ABI for `cancelDefaultAdminTransfer()` */\nconst CANCEL_DEFAULT_ADMIN_TRANSFER_ABI = [{\n\ttype: \"function\",\n\tname: \"cancelDefaultAdminTransfer\",\n\tinputs: [],\n\toutputs: [],\n\tstateMutability: \"nonpayable\"\n}];\n/** ABI for `changeDefaultAdminDelay(uint48 newDelay)` */\nconst CHANGE_DEFAULT_ADMIN_DELAY_ABI = [{\n\ttype: \"function\",\n\tname: \"changeDefaultAdminDelay\",\n\tinputs: [{\n\t\tname: \"newDelay\",\n\t\ttype: \"uint48\"\n\t}],\n\toutputs: [],\n\tstateMutability: \"nonpayable\"\n}];\n/** ABI for `rollbackDefaultAdminDelay()` */\nconst ROLLBACK_DEFAULT_ADMIN_DELAY_ABI = [{\n\ttype: \"function\",\n\tname: \"rollbackDefaultAdminDelay\",\n\tinputs: [],\n\toutputs: [],\n\tstateMutability: \"nonpayable\"\n}];\n/**\n* Function signature descriptors for ABI-based capability detection.\n* Used by `feature-detection.ts` to match function names AND parameter types\n* against the contract's ABI, avoiding false positives from similarly-named functions.\n*\n* @see contracts/feature-detection.ts for the full detection matrix\n*/\n/** Functions required for Ownable detection */\nconst OWNABLE_SIGNATURES = [{\n\tname: \"owner\",\n\tinputs: []\n}, {\n\tname: \"transferOwnership\",\n\tinputs: [\"address\"]\n}];\n/** Additional functions for Ownable2Step detection */\nconst OWNABLE_TWO_STEP_SIGNATURES = [{\n\tname: \"pendingOwner\",\n\tinputs: []\n}, {\n\tname: \"acceptOwnership\",\n\tinputs: []\n}];\n/** Functions required for AccessControl detection */\nconst ACCESS_CONTROL_SIGNATURES = [\n\t{\n\t\tname: \"hasRole\",\n\t\tinputs: [\"bytes32\", \"address\"]\n\t},\n\t{\n\t\tname: \"grantRole\",\n\t\tinputs: [\"bytes32\", \"address\"]\n\t},\n\t{\n\t\tname: \"revokeRole\",\n\t\tinputs: [\"bytes32\", \"address\"]\n\t},\n\t{\n\t\tname: \"getRoleAdmin\",\n\t\tinputs: [\"bytes32\"]\n\t}\n];\n/** Additional functions for AccessControlEnumerable detection */\nconst ENUMERABLE_SIGNATURES = [{\n\tname: \"getRoleMemberCount\",\n\tinputs: [\"bytes32\"]\n}, {\n\tname: \"getRoleMember\",\n\tinputs: [\"bytes32\", \"uint256\"]\n}];\n/** Additional functions for AccessControlDefaultAdminRules detection */\nconst DEFAULT_ADMIN_RULES_SIGNATURES = [\n\t{\n\t\tname: \"defaultAdmin\",\n\t\tinputs: []\n\t},\n\t{\n\t\tname: \"pendingDefaultAdmin\",\n\t\tinputs: []\n\t},\n\t{\n\t\tname: \"beginDefaultAdminTransfer\",\n\t\tinputs: [\"address\"]\n\t},\n\t{\n\t\tname: \"acceptDefaultAdminTransfer\",\n\t\tinputs: []\n\t},\n\t{\n\t\tname: \"cancelDefaultAdminTransfer\",\n\t\tinputs: []\n\t}\n];\n/** Additional functions for admin delay change operations */\nconst ADMIN_DELAY_CHANGE_SIGNATURES = [{\n\tname: \"changeDefaultAdminDelay\",\n\tinputs: [\"uint48\"]\n}, {\n\tname: \"rollbackDefaultAdminDelay\",\n\tinputs: []\n}];\n\n//#endregion\n//#region src/access-control/actions.ts\n/**\n* Assembles a `transferOwnership(address newOwner)` transaction.\n*\n* Works with both Ownable (single-step) and Ownable2Step (sets pendingOwner).\n* The contract determines the behavior — same function signature for both patterns.\n*\n* @param contractAddress - The target contract address (0x-prefixed)\n* @param newOwner - The new owner address (0x-prefixed)\n* @returns WriteContractParameters ready for execution\n*/\nfunction assembleTransferOwnershipAction(contractAddress, newOwner) {\n\treturn {\n\t\taddress: contractAddress,\n\t\tabi: TRANSFER_OWNERSHIP_ABI,\n\t\tfunctionName: \"transferOwnership\",\n\t\targs: [newOwner]\n\t};\n}\n/**\n* Assembles an `acceptOwnership()` transaction (Ownable2Step only).\n*\n* Must be called by the pending owner to complete a two-step transfer.\n* No arguments — the caller is implicitly the pending owner.\n*\n* @param contractAddress - The target contract address (0x-prefixed)\n* @returns WriteContractParameters ready for execution\n*/\nfunction assembleAcceptOwnershipAction(contractAddress) {\n\treturn {\n\t\taddress: contractAddress,\n\t\tabi: ACCEPT_OWNERSHIP_ABI,\n\t\tfunctionName: \"acceptOwnership\",\n\t\targs: []\n\t};\n}\n/**\n* Assembles a `renounceOwnership()` transaction (Ownable).\n*\n* Permanently renounces ownership — after execution, `owner()` returns the zero address.\n* This is an EVM-specific operation not present in the Stellar adapter.\n*\n* @param contractAddress - The target contract address (0x-prefixed)\n* @returns WriteContractParameters ready for execution\n*/\nfunction assembleRenounceOwnershipAction(contractAddress) {\n\treturn {\n\t\taddress: contractAddress,\n\t\tabi: RENOUNCE_OWNERSHIP_ABI,\n\t\tfunctionName: \"renounceOwnership\",\n\t\targs: []\n\t};\n}\n/**\n* Assembles a `beginDefaultAdminTransfer(address newAdmin)` transaction.\n*\n* Initiates a two-step admin transfer on an AccessControlDefaultAdminRules contract.\n* The transfer can be accepted after the contract's built-in delay period.\n*\n* @param contractAddress - The target contract address (0x-prefixed)\n* @param newAdmin - The new admin address (0x-prefixed)\n* @returns WriteContractParameters ready for execution\n*/\nfunction assembleBeginAdminTransferAction(contractAddress, newAdmin) {\n\treturn {\n\t\taddress: contractAddress,\n\t\tabi: BEGIN_DEFAULT_ADMIN_TRANSFER_ABI,\n\t\tfunctionName: \"beginDefaultAdminTransfer\",\n\t\targs: [newAdmin]\n\t};\n}\n/**\n* Assembles an `acceptDefaultAdminTransfer()` transaction.\n*\n* Must be called by the pending admin after the accept schedule timestamp\n* has passed. No arguments — the caller is implicitly the pending admin.\n*\n* @param contractAddress - The target contract address (0x-prefixed)\n* @returns WriteContractParameters ready for execution\n*/\nfunction assembleAcceptAdminTransferAction(contractAddress) {\n\treturn {\n\t\taddress: contractAddress,\n\t\tabi: ACCEPT_DEFAULT_ADMIN_TRANSFER_ABI,\n\t\tfunctionName: \"acceptDefaultAdminTransfer\",\n\t\targs: []\n\t};\n}\n/**\n* Assembles a `cancelDefaultAdminTransfer()` transaction.\n*\n* Cancels a pending admin transfer. Must be called by the current default admin.\n* EVM-specific operation — Stellar has no cancel mechanism.\n*\n* @param contractAddress - The target contract address (0x-prefixed)\n* @returns WriteContractParameters ready for execution\n*/\nfunction assembleCancelAdminTransferAction(contractAddress) {\n\treturn {\n\t\taddress: contractAddress,\n\t\tabi: CANCEL_DEFAULT_ADMIN_TRANSFER_ABI,\n\t\tfunctionName: \"cancelDefaultAdminTransfer\",\n\t\targs: []\n\t};\n}\n/**\n* Assembles a `changeDefaultAdminDelay(uint48 newDelay)` transaction.\n*\n* Schedules a change to the admin transfer delay. The delay change itself\n* has a delay before it takes effect.\n* EVM-specific operation — Stellar has no delay mechanism.\n*\n* @param contractAddress - The target contract address (0x-prefixed)\n* @param newDelay - The new delay in seconds (uint48)\n* @returns WriteContractParameters ready for execution\n*/\nfunction assembleChangeAdminDelayAction(contractAddress, newDelay) {\n\treturn {\n\t\taddress: contractAddress,\n\t\tabi: CHANGE_DEFAULT_ADMIN_DELAY_ABI,\n\t\tfunctionName: \"changeDefaultAdminDelay\",\n\t\targs: [newDelay]\n\t};\n}\n/**\n* Assembles a `rollbackDefaultAdminDelay()` transaction.\n*\n* Rolls back a pending admin delay change. Must be called by the current\n* default admin before the delay change takes effect.\n* EVM-specific operation — Stellar has no delay mechanism.\n*\n* @param contractAddress - The target contract address (0x-prefixed)\n* @returns WriteContractParameters ready for execution\n*/\nfunction assembleRollbackAdminDelayAction(contractAddress) {\n\treturn {\n\t\taddress: contractAddress,\n\t\tabi: ROLLBACK_DEFAULT_ADMIN_DELAY_ABI,\n\t\tfunctionName: \"rollbackDefaultAdminDelay\",\n\t\targs: []\n\t};\n}\n/**\n* Assembles a `grantRole(bytes32 role, address account)` transaction.\n*\n* Grants a role to an account. Must be called by an account with the role's\n* admin role (typically DEFAULT_ADMIN_ROLE for newly created roles).\n*\n* @param contractAddress - The target contract address (0x-prefixed)\n* @param roleId - The bytes32 role identifier\n* @param account - The account to grant the role to (0x-prefixed)\n* @returns WriteContractParameters ready for execution\n*/\nfunction assembleGrantRoleAction(contractAddress, roleId, account) {\n\treturn {\n\t\taddress: contractAddress,\n\t\tabi: GRANT_ROLE_ABI,\n\t\tfunctionName: \"grantRole\",\n\t\targs: [roleId, account]\n\t};\n}\n/**\n* Assembles a `revokeRole(bytes32 role, address account)` transaction.\n*\n* Revokes a role from an account. Must be called by an account with the\n* role's admin role.\n*\n* @param contractAddress - The target contract address (0x-prefixed)\n* @param roleId - The bytes32 role identifier\n* @param account - The account to revoke the role from (0x-prefixed)\n* @returns WriteContractParameters ready for execution\n*/\nfunction assembleRevokeRoleAction(contractAddress, roleId, account) {\n\treturn {\n\t\taddress: contractAddress,\n\t\tabi: REVOKE_ROLE_ABI,\n\t\tfunctionName: \"revokeRole\",\n\t\targs: [roleId, account]\n\t};\n}\n/**\n* Assembles a `renounceRole(bytes32 role, address callerConfirmation)` transaction.\n*\n* Renounces a role from the caller's own account. The `callerConfirmation` parameter\n* must match the caller's address — this is an on-chain safety check to prevent\n* accidental renouncement.\n*\n* **EVM-specific extension** — Stellar uses `revokeRole` for self-revocation instead\n* of a separate `renounceRole` function.\n*\n* @param contractAddress - The target contract address (0x-prefixed)\n* @param roleId - The bytes32 role identifier\n* @param account - The caller's address for confirmation (0x-prefixed)\n* @returns WriteContractParameters ready for execution\n*/\nfunction assembleRenounceRoleAction(contractAddress, roleId, account) {\n\treturn {\n\t\taddress: contractAddress,\n\t\tabi: RENOUNCE_ROLE_ABI,\n\t\tfunctionName: \"renounceRole\",\n\t\targs: [roleId, account]\n\t};\n}\n\n//#endregion\n//#region src/access-control/constants.ts\n/**\n* EVM Access Control Constants\n*\n* Shared constants for the access control module.\n* These values match OpenZeppelin's Solidity AccessControl contract definitions.\n*\n* @module access-control/constants\n*/\n/**\n* The bytes32 zero value used by OpenZeppelin AccessControl as the default admin role.\n* This is `keccak256(\"\")` equivalent — the admin role that governs all other roles by default.\n*\n* @see https://docs.openzeppelin.com/contracts/5.x/api/access#AccessControl-DEFAULT_ADMIN_ROLE--\n*/\nconst DEFAULT_ADMIN_ROLE = \"0x0000000000000000000000000000000000000000000000000000000000000000\";\n/**\n* Human-readable label for the default admin role.\n* Used when displaying role information in the Role Manager UI.\n*/\nconst DEFAULT_ADMIN_ROLE_LABEL = \"DEFAULT_ADMIN_ROLE\";\n/**\n* The EVM zero address (20 bytes of zeros).\n* Indicates renounced ownership or admin when returned by `owner()` or `defaultAdmin()`.\n*/\nconst ZERO_ADDRESS = \"0x0000000000000000000000000000000000000000\";\n/**\n* Well-known OpenZeppelin role hashes (pre-computed keccak256) mapped to human-readable labels.\n* Used for instant label resolution without on-chain calls.\n*\n* @see https://docs.openzeppelin.com/contracts/5.x/api/access\n*/\nconst WELL_KNOWN_ROLES = {\n\t[DEFAULT_ADMIN_ROLE]: DEFAULT_ADMIN_ROLE_LABEL,\n\t\"0x9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6\": \"MINTER_ROLE\",\n\t\"0x65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a\": \"PAUSER_ROLE\",\n\t\"0x3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a848\": \"BURNER_ROLE\",\n\t\"0x189ab7a9244df0848122154315af71fe140f3db0fe014031783b0946b8c9d2e3\": \"UPGRADER_ROLE\"\n};\n/**\n* Resolves a human-readable label for a role hash.\n* Checks the per-contract label map first (external + ABI labels),\n* then falls back to the well-known dictionary.\n*\n* @param roleId - bytes32 role identifier (0x-prefixed hex)\n* @param roleLabelMap - Optional per-contract map of hash -> label (external + ABI-extracted)\n* @returns Label string or undefined if not found\n*/\nfunction resolveRoleLabel(roleId, roleLabelMap) {\n\tconst normalized = roleId.toLowerCase();\n\treturn roleLabelMap?.get(normalized) ?? WELL_KNOWN_ROLES[normalized];\n}\n\n//#endregion\n//#region src/access-control/feature-detection.ts\n/**\n* Builds a lookup map from the contract schema's functions array.\n* Key is the function name; value is an array of input type arrays\n* (to handle overloaded functions with the same name but different params).\n*/\nfunction buildFunctionLookup(contractSchema) {\n\tconst lookup = /* @__PURE__ */ new Map();\n\tfor (const fn of contractSchema.functions) {\n\t\tconst inputTypes = fn.inputs.map((input) => input.type);\n\t\tconst existing = lookup.get(fn.name);\n\t\tif (existing) existing.push(inputTypes);\n\t\telse lookup.set(fn.name, [inputTypes]);\n\t}\n\treturn lookup;\n}\n/**\n* Checks whether a specific function signature exists in the lookup.\n* Matches both the function name and the parameter types.\n*/\nfunction hasFunction(lookup, sig) {\n\tconst overloads = lookup.get(sig.name);\n\tif (!overloads) return false;\n\treturn overloads.some((inputTypes) => {\n\t\tif (inputTypes.length !== sig.inputs.length) return false;\n\t\treturn inputTypes.every((type, i) => type === sig.inputs[i]);\n\t});\n}\n/**\n* Checks whether ALL signatures in a set are present in the lookup.\n*/\nfunction hasAllFunctions(lookup, signatures) {\n\treturn signatures.every((sig) => hasFunction(lookup, sig));\n}\n/**\n* Detect access control capabilities from a contract's ABI.\n*\n* Analyzes `ContractSchema.functions` for the presence of OpenZeppelin\n* access control function signatures, checking both function names AND\n* parameter types for accuracy.\n*\n* @param contractSchema - Parsed contract schema with functions array\n* @param indexerAvailable - Whether an indexer endpoint is configured and reachable\n* @returns Detected capabilities flags\n*/\nfunction detectAccessControlCapabilities(contractSchema, indexerAvailable = false) {\n\tconst lookup = buildFunctionLookup(contractSchema);\n\tconst hasOwnable = hasAllFunctions(lookup, OWNABLE_SIGNATURES);\n\tconst hasTwoStepOwnable = hasOwnable && hasAllFunctions(lookup, OWNABLE_TWO_STEP_SIGNATURES);\n\tconst hasAccessControl = hasAllFunctions(lookup, ACCESS_CONTROL_SIGNATURES);\n\tconst hasEnumerableRoles = hasAccessControl && hasAllFunctions(lookup, ENUMERABLE_SIGNATURES);\n\tconst hasTwoStepAdmin = hasAccessControl && hasAllFunctions(lookup, DEFAULT_ADMIN_RULES_SIGNATURES);\n\tconst hasRenounceOwnership = hasOwnable && hasFunction(lookup, {\n\t\tname: \"renounceOwnership\",\n\t\tinputs: []\n\t});\n\tconst hasRenounceRole = hasAccessControl && hasFunction(lookup, {\n\t\tname: \"renounceRole\",\n\t\tinputs: [\"bytes32\", \"address\"]\n\t});\n\tconst hasCancelAdminTransfer = hasTwoStepAdmin && hasFunction(lookup, {\n\t\tname: \"cancelDefaultAdminTransfer\",\n\t\tinputs: []\n\t});\n\tconst hasAdminDelayManagement = hasTwoStepAdmin && hasAllFunctions(lookup, ADMIN_DELAY_CHANGE_SIGNATURES);\n\tconst supportsHistory = indexerAvailable;\n\tconst verifiedAgainstOZInterfaces = hasOwnable || hasAccessControl;\n\tconst notes = [];\n\tif (hasOwnable) if (hasTwoStepOwnable) notes.push(\"OpenZeppelin Ownable2Step interface detected (with pendingOwner + acceptOwnership)\");\n\telse notes.push(\"OpenZeppelin Ownable interface detected\");\n\tif (hasAccessControl) {\n\t\tif (hasTwoStepAdmin) notes.push(\"OpenZeppelin AccessControlDefaultAdminRules interface detected\");\n\t\telse notes.push(\"OpenZeppelin AccessControl interface detected\");\n\t\tif (hasEnumerableRoles) notes.push(\"Role enumeration supported (getRoleMemberCount, getRoleMember)\");\n\t\telse notes.push(\"Role enumeration not available — requires known role IDs or indexer discovery\");\n\t}\n\tif (!indexerAvailable && (hasOwnable || hasAccessControl)) notes.push(\"History queries unavailable without indexer configuration\");\n\tif (!hasOwnable && !hasAccessControl) notes.push(\"No OpenZeppelin access control interfaces detected\");\n\treturn {\n\t\thasOwnable,\n\t\thasTwoStepOwnable,\n\t\thasAccessControl,\n\t\thasTwoStepAdmin,\n\t\thasEnumerableRoles,\n\t\tsupportsHistory,\n\t\tverifiedAgainstOZInterfaces,\n\t\tnotes: notes.length > 0 ? notes : void 0,\n\t\thasRenounceOwnership,\n\t\thasRenounceRole,\n\t\thasCancelAdminTransfer,\n\t\thasAdminDelayManagement\n\t};\n}\n/**\n* Validate that a contract has minimum viable access control support.\n*\n* Returns `true` if the contract has at least Ownable or AccessControl.\n* Unlike the Stellar adapter's version (which throws), this returns a boolean\n* for simpler integration — callers can decide how to handle unsupported contracts.\n*\n* @param capabilities - Previously detected capabilities\n* @returns true if the contract has at least Ownable or AccessControl\n*/\nfunction validateAccessControlSupport(capabilities) {\n\treturn capabilities.hasOwnable || capabilities.hasAccessControl;\n}\n\n//#endregion\n//#region src/access-control/indexer-client.ts\nconst LOG_SYSTEM$2 = \"EvmIndexerClient\";\n/**\n* Build the composite key used for grant map lookups.\n*\n* Keys on `role:account` (both lowercased) so that an account holding\n* multiple roles gets a distinct entry per role, avoiding stale grant\n* metadata cross-contamination.\n*\n* @param roleId - The bytes32 role identifier\n* @param account - The account address\n* @returns A composite key in the form `roleId:account` (lowercased)\n*/\nfunction grantMapKey(roleId, account) {\n\treturn `${roleId.toLowerCase()}:${account.toLowerCase()}`;\n}\nconst HEALTH_CHECK_QUERY = \"{ __typename }\";\nconst PENDING_OWNERSHIP_TRANSFER_QUERY = `\n  query GetPendingOwnershipTransfer($network: String!, $contract: String!) {\n    accessControlEvents(\n      filter: {\n        network: { equalTo: $network }\n        contract: { equalTo: $contract }\n        eventType: { equalTo: OWNERSHIP_TRANSFER_STARTED }\n      }\n      first: 1\n      orderBy: TIMESTAMP_DESC\n    ) {\n      nodes {\n        id\n        eventType\n        blockNumber\n        timestamp\n        txHash\n        newOwner\n      }\n    }\n  }\n`;\nconst ROLE_MEMBERSHIPS_QUERY = `\n  query GetRoleMembers($network: String!, $contract: String!, $roles: [String!]) {\n    roleMemberships(\n      filter: {\n        network: { equalTo: $network }\n        contract: { equalTo: $contract }\n        role: { in: $roles }\n      }\n      orderBy: GRANTED_AT_DESC\n    ) {\n      nodes {\n        role\n        account\n        grantedAt\n        grantedBy\n        txHash\n      }\n    }\n  }\n`;\nconst DISCOVER_ROLES_QUERY = `\n  query DiscoverRoles($network: String!, $contract: String!) {\n    accessControlEvents(\n      filter: {\n        network: { equalTo: $network }\n        contract: { equalTo: $contract }\n      }\n      first: 1000\n      orderBy: TIMESTAMP_DESC\n    ) {\n      nodes {\n        role\n      }\n    }\n  }\n`;\nconst PENDING_ADMIN_TRANSFER_QUERY = `\n  query GetPendingAdminTransfer($network: String!, $contract: String!) {\n    accessControlEvents(\n      filter: {\n        network: { equalTo: $network }\n        contract: { equalTo: $contract }\n        eventType: { in: [DEFAULT_ADMIN_TRANSFER_SCHEDULED, ADMIN_TRANSFER_INITIATED] }\n      }\n      first: 1\n      orderBy: TIMESTAMP_DESC\n    ) {\n      nodes {\n        id\n        eventType\n        blockNumber\n        timestamp\n        txHash\n        newAdmin\n        acceptSchedule\n      }\n    }\n  }\n`;\n/**\n* Maps all 13 EVM indexer event types to unified HistoryChangeType values.\n*\n* 10 types map directly. 3 EVM-specific types (DEFAULT_ADMIN_TRANSFER_CANCELED,\n* DEFAULT_ADMIN_DELAY_CHANGE_SCHEDULED, DEFAULT_ADMIN_DELAY_CHANGE_CANCELED)\n* map to their PR-2 variants (ADMIN_TRANSFER_CANCELED, ADMIN_DELAY_CHANGE_SCHEDULED,\n* ADMIN_DELAY_CHANGE_CANCELED) which are now available in @openzeppelin/ui-types@1.7.0.\n*\n* DEFAULT_ADMIN_TRANSFER_SCHEDULED is an EVM-specific alias for ADMIN_TRANSFER_INITIATED.\n*/\nconst EVM_EVENT_TYPE_TO_CHANGE_TYPE = {\n\tROLE_GRANTED: \"GRANTED\",\n\tROLE_REVOKED: \"REVOKED\",\n\tROLE_ADMIN_CHANGED: \"ROLE_ADMIN_CHANGED\",\n\tOWNERSHIP_TRANSFER_STARTED: \"OWNERSHIP_TRANSFER_STARTED\",\n\tOWNERSHIP_TRANSFER_COMPLETED: \"OWNERSHIP_TRANSFER_COMPLETED\",\n\tOWNERSHIP_RENOUNCED: \"OWNERSHIP_RENOUNCED\",\n\tADMIN_TRANSFER_INITIATED: \"ADMIN_TRANSFER_INITIATED\",\n\tADMIN_TRANSFER_COMPLETED: \"ADMIN_TRANSFER_COMPLETED\",\n\tADMIN_RENOUNCED: \"ADMIN_RENOUNCED\",\n\tDEFAULT_ADMIN_TRANSFER_SCHEDULED: \"ADMIN_TRANSFER_INITIATED\",\n\tDEFAULT_ADMIN_TRANSFER_CANCELED: \"ADMIN_TRANSFER_CANCELED\",\n\tDEFAULT_ADMIN_DELAY_CHANGE_SCHEDULED: \"ADMIN_DELAY_CHANGE_SCHEDULED\",\n\tDEFAULT_ADMIN_DELAY_CHANGE_CANCELED: \"ADMIN_DELAY_CHANGE_CANCELED\"\n};\n/**\n* Reverse mapping: HistoryChangeType → EVM indexer GraphQL enum value.\n* Used to filter by event type in history queries.\n*/\nconst CHANGE_TYPE_TO_EVENT_TYPE = {\n\tGRANTED: \"ROLE_GRANTED\",\n\tREVOKED: \"ROLE_REVOKED\",\n\tROLE_ADMIN_CHANGED: \"ROLE_ADMIN_CHANGED\",\n\tOWNERSHIP_TRANSFER_STARTED: \"OWNERSHIP_TRANSFER_STARTED\",\n\tOWNERSHIP_TRANSFER_COMPLETED: \"OWNERSHIP_TRANSFER_COMPLETED\",\n\tOWNERSHIP_RENOUNCED: \"OWNERSHIP_RENOUNCED\",\n\tADMIN_TRANSFER_INITIATED: \"ADMIN_TRANSFER_INITIATED\",\n\tADMIN_TRANSFER_COMPLETED: \"ADMIN_TRANSFER_COMPLETED\",\n\tADMIN_TRANSFER_CANCELED: \"DEFAULT_ADMIN_TRANSFER_CANCELED\",\n\tADMIN_RENOUNCED: \"ADMIN_RENOUNCED\",\n\tADMIN_DELAY_CHANGE_SCHEDULED: \"DEFAULT_ADMIN_DELAY_CHANGE_SCHEDULED\",\n\tADMIN_DELAY_CHANGE_CANCELED: \"DEFAULT_ADMIN_DELAY_CHANGE_CANCELED\",\n\tUNKNOWN: \"UNKNOWN\"\n};\n/**\n* EVM Indexer Client\n*\n* Handles GraphQL queries to the configured indexer for historical access control data.\n* The client is designed for graceful degradation — all query methods return null\n* instead of throwing when the indexer is unavailable.\n*/\nvar EvmIndexerClient = class {\n\tnetworkConfig;\n\tendpoint;\n\tavailabilityChecked = false;\n\tavailable = false;\n\tconstructor(networkConfig) {\n\t\tthis.networkConfig = networkConfig;\n\t\tthis.endpoint = resolveAccessControlIndexerUrl(networkConfig);\n\t}\n\t/**\n\t* Check if the indexer is available and configured.\n\t*\n\t* Performs a lightweight health check (`{ __typename }`) on the first call,\n\t* then caches the result for subsequent calls.\n\t*\n\t* @returns true if the indexer endpoint is configured and responds to health checks\n\t*/\n\tasync isAvailable() {\n\t\tif (this.availabilityChecked) return this.available;\n\t\tif (!this.endpoint) {\n\t\t\tlogger.info(LOG_SYSTEM$2, `No indexer configured for network ${this.networkConfig.id}`);\n\t\t\tthis.availabilityChecked = true;\n\t\t\tthis.available = false;\n\t\t\treturn false;\n\t\t}\n\t\ttry {\n\t\t\tconst response = await fetch(this.endpoint, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\tbody: JSON.stringify({ query: HEALTH_CHECK_QUERY })\n\t\t\t});\n\t\t\tif (response.ok) {\n\t\t\t\tlogger.info(LOG_SYSTEM$2, `Indexer available for network ${this.networkConfig.id} at ${this.endpoint}`);\n\t\t\t\tthis.available = true;\n\t\t\t} else {\n\t\t\t\tlogger.warn(LOG_SYSTEM$2, `Indexer endpoint ${this.endpoint} returned status ${response.status}`);\n\t\t\t\tthis.available = false;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tlogger.warn(LOG_SYSTEM$2, `Failed to connect to indexer at ${this.endpoint}: ${error instanceof Error ? error.message : String(error)}`);\n\t\t\tthis.available = false;\n\t\t}\n\t\tthis.availabilityChecked = true;\n\t\treturn this.available;\n\t}\n\t/**\n\t* Query the indexer for the latest pending ownership transfer event.\n\t*\n\t* Queries for `OWNERSHIP_TRANSFER_STARTED` events, ordered by timestamp descending.\n\t* Returns the most recent event if found, or null if no pending transfer exists.\n\t*\n\t* Graceful degradation: returns null if the indexer is unavailable or the query fails.\n\t*\n\t* @param contractAddress - The contract address to query\n\t* @returns Pending transfer data or null\n\t*/\n\tasync queryPendingOwnershipTransfer(contractAddress) {\n\t\tif (!await this.isAvailable() || !this.endpoint) return null;\n\t\tlogger.info(LOG_SYSTEM$2, `Querying pending ownership transfer for ${contractAddress}`);\n\t\ttry {\n\t\t\tconst response = await fetch(this.endpoint, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tquery: PENDING_OWNERSHIP_TRANSFER_QUERY,\n\t\t\t\t\tvariables: {\n\t\t\t\t\t\tnetwork: this.networkConfig.id,\n\t\t\t\t\t\tcontract: contractAddress\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t});\n\t\t\tif (!response.ok) {\n\t\t\t\tlogger.warn(LOG_SYSTEM$2, `Indexer query failed with status ${response.status} for ownership transfer`);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst result = await response.json();\n\t\t\tif (result.errors && result.errors.length > 0) {\n\t\t\t\tlogger.warn(LOG_SYSTEM$2, `Indexer query errors: ${result.errors.map((e) => e.message).join(\"; \")}`);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst nodes = result.data?.accessControlEvents?.nodes;\n\t\t\tif (!nodes || nodes.length === 0) {\n\t\t\t\tlogger.debug(LOG_SYSTEM$2, `No pending ownership transfer found for ${contractAddress}`);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst event = nodes[0];\n\t\t\tif (!event.newOwner) {\n\t\t\t\tlogger.warn(LOG_SYSTEM$2, `OWNERSHIP_TRANSFER_STARTED event missing newOwner for ${contractAddress}`);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tpendingOwner: event.newOwner,\n\t\t\t\tinitiatedAt: event.timestamp,\n\t\t\t\tinitiatedTxId: event.txHash,\n\t\t\t\tinitiatedBlock: parseInt(event.blockNumber, 10)\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tlogger.warn(LOG_SYSTEM$2, `Failed to query pending ownership transfer: ${error instanceof Error ? error.message : String(error)}`);\n\t\t\treturn null;\n\t\t}\n\t}\n\t/**\n\t* Query the indexer for the latest pending admin transfer event.\n\t*\n\t* Queries for `DEFAULT_ADMIN_TRANSFER_SCHEDULED` or `ADMIN_TRANSFER_INITIATED` events,\n\t* ordered by timestamp descending. Returns the most recent event if found,\n\t* or null if no pending transfer exists.\n\t*\n\t* Graceful degradation: returns null if the indexer is unavailable or the query fails.\n\t*\n\t* @param contractAddress - The contract address to query\n\t* @returns Pending admin transfer data or null\n\t*/\n\tasync queryPendingAdminTransfer(contractAddress) {\n\t\tif (!await this.isAvailable() || !this.endpoint) return null;\n\t\tlogger.info(LOG_SYSTEM$2, `Querying pending admin transfer for ${contractAddress}`);\n\t\ttry {\n\t\t\tconst response = await fetch(this.endpoint, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tquery: PENDING_ADMIN_TRANSFER_QUERY,\n\t\t\t\t\tvariables: {\n\t\t\t\t\t\tnetwork: this.networkConfig.id,\n\t\t\t\t\t\tcontract: contractAddress\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t});\n\t\t\tif (!response.ok) {\n\t\t\t\tlogger.warn(LOG_SYSTEM$2, `Indexer query failed with status ${response.status} for admin transfer`);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst result = await response.json();\n\t\t\tif (result.errors && result.errors.length > 0) {\n\t\t\t\tlogger.warn(LOG_SYSTEM$2, `Indexer query errors: ${result.errors.map((e) => e.message).join(\"; \")}`);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst nodes = result.data?.accessControlEvents?.nodes;\n\t\t\tif (!nodes || nodes.length === 0) {\n\t\t\t\tlogger.debug(LOG_SYSTEM$2, `No pending admin transfer found for ${contractAddress}`);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst event = nodes[0];\n\t\t\tif (!event.newAdmin) {\n\t\t\t\tlogger.warn(LOG_SYSTEM$2, `Admin transfer event missing newAdmin for ${contractAddress}`);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tpendingAdmin: event.newAdmin,\n\t\t\t\tacceptSchedule: event.acceptSchedule ? parseInt(event.acceptSchedule, 10) : 0,\n\t\t\t\tinitiatedAt: event.timestamp,\n\t\t\t\tinitiatedTxId: event.txHash,\n\t\t\t\tinitiatedBlock: parseInt(event.blockNumber, 10)\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tlogger.warn(LOG_SYSTEM$2, `Failed to query pending admin transfer: ${error instanceof Error ? error.message : String(error)}`);\n\t\t\treturn null;\n\t\t}\n\t}\n\t/**\n\t* Query the indexer for current role membership grant data.\n\t*\n\t* Queries `roleMemberships` for the specified roles, returning a map of\n\t* `role:account → GrantInfo` for enrichment of role assignments. The composite\n\t* key ensures that an account holding multiple roles retains distinct grant\n\t* metadata per role. Use {@link grantMapKey} to build lookup keys.\n\t*\n\t* Returns an empty Map if roleIds is empty. Returns null if the indexer\n\t* is unavailable or the query fails (graceful degradation).\n\t*\n\t* @param contractAddress - The contract address to query\n\t* @param roleIds - Array of bytes32 role IDs to query\n\t* @returns Map of `role:account` composite key to GrantInfo, or null on failure\n\t*/\n\tasync queryLatestGrants(contractAddress, roleIds) {\n\t\tif (roleIds.length === 0) return /* @__PURE__ */ new Map();\n\t\tif (!await this.isAvailable() || !this.endpoint) return null;\n\t\tlogger.info(LOG_SYSTEM$2, `Querying latest grants for ${roleIds.length} role(s) on ${contractAddress}`);\n\t\ttry {\n\t\t\tconst response = await fetch(this.endpoint, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tquery: ROLE_MEMBERSHIPS_QUERY,\n\t\t\t\t\tvariables: {\n\t\t\t\t\t\tnetwork: this.networkConfig.id,\n\t\t\t\t\t\tcontract: contractAddress,\n\t\t\t\t\t\troles: roleIds\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t});\n\t\t\tif (!response.ok) {\n\t\t\t\tlogger.warn(LOG_SYSTEM$2, `Indexer query failed with status ${response.status} for role memberships`);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst result = await response.json();\n\t\t\tif (result.errors && result.errors.length > 0) {\n\t\t\t\tlogger.warn(LOG_SYSTEM$2, `Indexer query errors: ${result.errors.map((e) => e.message).join(\"; \")}`);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst nodes = result.data?.roleMemberships?.nodes;\n\t\t\tif (!nodes || nodes.length === 0) {\n\t\t\t\tlogger.debug(LOG_SYSTEM$2, `No role membership data found for ${contractAddress}`);\n\t\t\t\treturn /* @__PURE__ */ new Map();\n\t\t\t}\n\t\t\tconst grantMap = /* @__PURE__ */ new Map();\n\t\t\tfor (const node of nodes) {\n\t\t\t\tconst key = grantMapKey(node.role, node.account);\n\t\t\t\tif (!grantMap.has(key)) grantMap.set(key, {\n\t\t\t\t\taccount: node.account,\n\t\t\t\t\trole: node.role,\n\t\t\t\t\tgrantedAt: node.grantedAt,\n\t\t\t\t\ttxHash: node.txHash,\n\t\t\t\t\tgrantedBy: node.grantedBy\n\t\t\t\t});\n\t\t\t}\n\t\t\tlogger.debug(LOG_SYSTEM$2, `Found grant info for ${grantMap.size} member(s) across ${roleIds.length} role(s)`);\n\t\t\treturn grantMap;\n\t\t} catch (error) {\n\t\t\tlogger.warn(LOG_SYSTEM$2, `Failed to query latest grants: ${error instanceof Error ? error.message : String(error)}`);\n\t\t\treturn null;\n\t\t}\n\t}\n\t/**\n\t* Discover all unique role identifiers for a contract by querying historical events.\n\t*\n\t* Queries all `accessControlEvents` for the contract and extracts unique, non-empty\n\t* `role` values. This enables role enumeration even when `knownRoleIds` are not\n\t* provided at registration.\n\t*\n\t* Graceful degradation: returns null if the indexer is unavailable or the query fails.\n\t*\n\t* @param contractAddress - The contract address to discover roles for\n\t* @returns Array of unique role identifiers, or null on failure\n\t*/\n\tasync discoverRoleIds(contractAddress) {\n\t\tif (!await this.isAvailable() || !this.endpoint) return null;\n\t\tlogger.info(LOG_SYSTEM$2, `Discovering role IDs for ${contractAddress}`);\n\t\ttry {\n\t\t\tconst response = await fetch(this.endpoint, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tquery: DISCOVER_ROLES_QUERY,\n\t\t\t\t\tvariables: {\n\t\t\t\t\t\tnetwork: this.networkConfig.id,\n\t\t\t\t\t\tcontract: contractAddress\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t});\n\t\t\tif (!response.ok) {\n\t\t\t\tlogger.warn(LOG_SYSTEM$2, `Indexer query failed with status ${response.status} for role discovery`);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst result = await response.json();\n\t\t\tif (result.errors && result.errors.length > 0) {\n\t\t\t\tlogger.warn(LOG_SYSTEM$2, `Indexer query errors: ${result.errors.map((e) => e.message).join(\"; \")}`);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst nodes = result.data?.accessControlEvents?.nodes;\n\t\t\tif (!nodes || nodes.length === 0) {\n\t\t\t\tlogger.debug(LOG_SYSTEM$2, `No events found for role discovery on ${contractAddress}`);\n\t\t\t\treturn [];\n\t\t\t}\n\t\t\tconst uniqueRoles = [...new Set(nodes.map((n) => n.role).filter((r) => !!r))];\n\t\t\tlogger.debug(LOG_SYSTEM$2, `Discovered ${uniqueRoles.length} unique role(s) for ${contractAddress}`);\n\t\t\treturn uniqueRoles;\n\t\t} catch (error) {\n\t\t\tlogger.warn(LOG_SYSTEM$2, `Failed to discover role IDs: ${error instanceof Error ? error.message : String(error)}`);\n\t\t\treturn null;\n\t\t}\n\t}\n\t/**\n\t* Query historical access control events with filtering and pagination.\n\t*\n\t* Queries `accessControlEvents` with the specified filters. All 13 EVM event types\n\t* are mapped to `HistoryChangeType` values per research.md §R6.\n\t*\n\t* Graceful degradation: returns null if the indexer is unavailable or the query fails.\n\t*\n\t* @param contractAddress - The contract address to query\n\t* @param options - Optional filtering and pagination options\n\t* @returns Paginated history result, or null on failure\n\t*/\n\tasync queryHistory(contractAddress, options, roleLabelMap) {\n\t\tif (!await this.isAvailable() || !this.endpoint) return null;\n\t\tlogger.info(LOG_SYSTEM$2, `Querying history for ${contractAddress}`);\n\t\tconst query = this.buildHistoryQuery(options);\n\t\tconst variables = this.buildHistoryVariables(contractAddress, options);\n\t\ttry {\n\t\t\tconst response = await fetch(this.endpoint, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tquery,\n\t\t\t\t\tvariables\n\t\t\t\t})\n\t\t\t});\n\t\t\tif (!response.ok) {\n\t\t\t\tlogger.warn(LOG_SYSTEM$2, `Indexer query failed with status ${response.status} for history`);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst result = await response.json();\n\t\t\tif (result.errors && result.errors.length > 0) {\n\t\t\t\tlogger.warn(LOG_SYSTEM$2, `Indexer query errors: ${result.errors.map((e) => e.message).join(\"; \")}`);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst nodes = result.data?.accessControlEvents?.nodes;\n\t\t\tif (!nodes || nodes.length === 0) {\n\t\t\t\tlogger.debug(LOG_SYSTEM$2, `No history events found for ${contractAddress}`);\n\t\t\t\treturn {\n\t\t\t\t\titems: [],\n\t\t\t\t\tpageInfo: { hasNextPage: false }\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst items = this.transformToHistoryEntries(nodes, roleLabelMap);\n\t\t\tconst pageInfo = {\n\t\t\t\thasNextPage: result.data?.accessControlEvents?.pageInfo?.hasNextPage ?? false,\n\t\t\t\tendCursor: result.data?.accessControlEvents?.pageInfo?.endCursor\n\t\t\t};\n\t\t\tlogger.debug(LOG_SYSTEM$2, `Retrieved ${items.length} history event(s) for ${contractAddress}`);\n\t\t\treturn {\n\t\t\t\titems,\n\t\t\t\tpageInfo\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tlogger.warn(LOG_SYSTEM$2, `Failed to query history: ${error instanceof Error ? error.message : String(error)}`);\n\t\t\treturn null;\n\t\t}\n\t}\n\t/**\n\t* Builds the dynamic GraphQL history query with conditional filter clauses.\n\t*\n\t* Filter conditions are added only when the corresponding option is present.\n\t* EventType filter uses inline GraphQL enum values (not quoted strings).\n\t*/\n\tbuildHistoryQuery(options) {\n\t\tconst roleFilter = options?.roleId ? \", role: { equalTo: $role }\" : \"\";\n\t\tconst accountFilter = options?.account ? \", account: { equalTo: $account }\" : \"\";\n\t\tconst typeFilter = options?.changeType ? `, eventType: { equalTo: ${CHANGE_TYPE_TO_EVENT_TYPE[options.changeType]} }` : \"\";\n\t\tconst txFilter = options?.txId ? \", txHash: { equalTo: $txHash }\" : \"\";\n\t\tconst timestampConditions = [];\n\t\tif (options?.timestampFrom) timestampConditions.push(\"greaterThanOrEqualTo: $timestampFrom\");\n\t\tif (options?.timestampTo) timestampConditions.push(\"lessThanOrEqualTo: $timestampTo\");\n\t\tconst timestampFilter = timestampConditions.length > 0 ? `, timestamp: { ${timestampConditions.join(\", \")} }` : \"\";\n\t\tconst ledgerFilter = options?.ledger ? \", blockNumber: { equalTo: $blockNumber }\" : \"\";\n\t\tconst limitClause = options?.limit ? \", first: $limit\" : \"\";\n\t\tconst cursorClause = options?.cursor ? \", after: $cursor\" : \"\";\n\t\treturn `\n      query GetHistory(${[\n\t\t\t\"$network: String!\",\n\t\t\t\"$contract: String!\",\n\t\t\toptions?.roleId ? \"$role: String\" : \"\",\n\t\t\toptions?.account ? \"$account: String\" : \"\",\n\t\t\toptions?.txId ? \"$txHash: String\" : \"\",\n\t\t\toptions?.timestampFrom ? \"$timestampFrom: Datetime\" : \"\",\n\t\t\toptions?.timestampTo ? \"$timestampTo: Datetime\" : \"\",\n\t\t\toptions?.ledger ? \"$blockNumber: BigFloat\" : \"\",\n\t\t\toptions?.limit ? \"$limit: Int\" : \"\",\n\t\t\toptions?.cursor ? \"$cursor: Cursor\" : \"\"\n\t\t].filter(Boolean).join(\", \")}) {\n        accessControlEvents(\n          filter: {\n            network: { equalTo: $network }\n            contract: { equalTo: $contract }${roleFilter}${accountFilter}${typeFilter}${txFilter}${timestampFilter}${ledgerFilter}\n          }\n          orderBy: TIMESTAMP_DESC${limitClause}${cursorClause}\n        ) {\n          nodes {\n            id\n            eventType\n            blockNumber\n            timestamp\n            txHash\n            role\n            account\n            newOwner\n            newAdmin\n            acceptSchedule\n          }\n          totalCount\n          pageInfo {\n            hasNextPage\n            endCursor\n          }\n        }\n      }\n    `;\n\t}\n\t/**\n\t* Builds query variables for history queries, mapping options to GraphQL variables.\n\t*/\n\tbuildHistoryVariables(contractAddress, options) {\n\t\tconst variables = {\n\t\t\tnetwork: this.networkConfig.id,\n\t\t\tcontract: contractAddress\n\t\t};\n\t\tif (options?.roleId) variables.role = options.roleId;\n\t\tif (options?.account) variables.account = options.account;\n\t\tif (options?.txId) variables.txHash = options.txId;\n\t\tif (options?.timestampFrom) variables.timestampFrom = options.timestampFrom;\n\t\tif (options?.timestampTo) variables.timestampTo = options.timestampTo;\n\t\tif (options?.ledger) variables.blockNumber = String(options.ledger);\n\t\tif (options?.limit) variables.limit = options.limit;\n\t\tif (options?.cursor) variables.cursor = options.cursor;\n\t\treturn variables;\n\t}\n\t/**\n\t* Transforms indexer event nodes to unified HistoryEntry format.\n\t*\n\t* Maps EVM event types to HistoryChangeType, normalizes account field\n\t* based on event type (role → account, ownership → newOwner, admin → newAdmin),\n\t* and resolves the role identifier using event-type-aware logic so that\n\t* `role.id` is always a valid bytes32 hex string in the EVM context.\n\t*/\n\ttransformToHistoryEntries(nodes, roleLabelMap) {\n\t\treturn nodes.map((node) => {\n\t\t\tconst role = this.resolveRoleFromEvent(node, roleLabelMap);\n\t\t\tconst changeType = this.mapEventTypeToChangeType(node.eventType);\n\t\t\treturn {\n\t\t\t\trole,\n\t\t\t\taccount: this.normalizeAccountFromEvent(node),\n\t\t\t\tchangeType,\n\t\t\t\ttxId: node.txHash,\n\t\t\t\ttimestamp: node.timestamp,\n\t\t\t\tledger: parseInt(node.blockNumber, 10)\n\t\t\t};\n\t\t});\n\t}\n\t/**\n\t* Resolves the RoleIdentifier from an indexer event node based on event type.\n\t*\n\t* - **Role events** (ROLE_GRANTED, ROLE_REVOKED, ROLE_ADMIN_CHANGED): Use the\n\t*   actual `node.role` bytes32 value from the indexed event; label from\n\t*   roleLabelMap or well-known dictionary.\n\t* - **Ownership events** (OWNERSHIP_*): The Ownable pattern has no AccessControl\n\t*   role, so we use `DEFAULT_ADMIN_ROLE` (bytes32 zero) as a canonical sentinel\n\t*   with `label: 'OWNER'` for display context.\n\t* - **Admin events** (ADMIN_*, DEFAULT_ADMIN_*): These events concern the default\n\t*   admin role, so we use `DEFAULT_ADMIN_ROLE` with its standard label.\n\t*\n\t* This ensures `role.id` is always a valid bytes32 hex string, maintaining\n\t* consistency with EVM's address/role format conventions. Consumers can use\n\t* `role.label` to distinguish ownership vs. admin events.\n\t*/\n\tresolveRoleFromEvent(node, roleLabelMap) {\n\t\tconst roleId = node.role || DEFAULT_ADMIN_ROLE;\n\t\tswitch (node.eventType) {\n\t\t\tcase \"ROLE_GRANTED\":\n\t\t\tcase \"ROLE_REVOKED\":\n\t\t\tcase \"ROLE_ADMIN_CHANGED\": return {\n\t\t\t\tid: roleId,\n\t\t\t\tlabel: resolveRoleLabel(roleId, roleLabelMap)\n\t\t\t};\n\t\t\tcase \"OWNERSHIP_TRANSFER_STARTED\":\n\t\t\tcase \"OWNERSHIP_TRANSFER_COMPLETED\":\n\t\t\tcase \"OWNERSHIP_RENOUNCED\": return {\n\t\t\t\tid: DEFAULT_ADMIN_ROLE,\n\t\t\t\tlabel: \"OWNER\"\n\t\t\t};\n\t\t\tcase \"ADMIN_TRANSFER_INITIATED\":\n\t\t\tcase \"ADMIN_TRANSFER_COMPLETED\":\n\t\t\tcase \"ADMIN_RENOUNCED\":\n\t\t\tcase \"DEFAULT_ADMIN_TRANSFER_SCHEDULED\":\n\t\t\tcase \"DEFAULT_ADMIN_TRANSFER_CANCELED\":\n\t\t\tcase \"DEFAULT_ADMIN_DELAY_CHANGE_SCHEDULED\":\n\t\t\tcase \"DEFAULT_ADMIN_DELAY_CHANGE_CANCELED\": return {\n\t\t\t\tid: DEFAULT_ADMIN_ROLE,\n\t\t\t\tlabel: DEFAULT_ADMIN_ROLE_LABEL\n\t\t\t};\n\t\t\tdefault: return {\n\t\t\t\tid: roleId,\n\t\t\t\tlabel: resolveRoleLabel(roleId, roleLabelMap)\n\t\t\t};\n\t\t}\n\t}\n\t/**\n\t* Maps an EVM indexer event type string to the unified HistoryChangeType.\n\t* Returns 'UNKNOWN' for unrecognized event types.\n\t*/\n\tmapEventTypeToChangeType(eventType) {\n\t\tconst mapped = EVM_EVENT_TYPE_TO_CHANGE_TYPE[eventType];\n\t\tif (mapped) return mapped;\n\t\tlogger.warn(LOG_SYSTEM$2, `Unknown event type: ${eventType}, assigning changeType to UNKNOWN`);\n\t\treturn \"UNKNOWN\";\n\t}\n\t/**\n\t* Normalizes the account field from an indexer event node.\n\t*\n\t* Different event types store the relevant account in different fields:\n\t* - Role events (ROLE_GRANTED, ROLE_REVOKED, ROLE_ADMIN_CHANGED): `account`\n\t* - Ownership events: `newOwner`\n\t* - Admin events: `newAdmin`\n\t* - Fallback: `account` or empty string\n\t*/\n\tnormalizeAccountFromEvent(node) {\n\t\tswitch (node.eventType) {\n\t\t\tcase \"ROLE_GRANTED\":\n\t\t\tcase \"ROLE_REVOKED\":\n\t\t\tcase \"ROLE_ADMIN_CHANGED\": return node.account || \"\";\n\t\t\tcase \"OWNERSHIP_TRANSFER_STARTED\":\n\t\t\tcase \"OWNERSHIP_TRANSFER_COMPLETED\":\n\t\t\tcase \"OWNERSHIP_RENOUNCED\": return node.newOwner || \"\";\n\t\t\tcase \"ADMIN_TRANSFER_INITIATED\":\n\t\t\tcase \"ADMIN_TRANSFER_COMPLETED\":\n\t\t\tcase \"ADMIN_RENOUNCED\":\n\t\t\tcase \"DEFAULT_ADMIN_TRANSFER_SCHEDULED\":\n\t\t\tcase \"DEFAULT_ADMIN_TRANSFER_CANCELED\":\n\t\t\tcase \"DEFAULT_ADMIN_DELAY_CHANGE_SCHEDULED\":\n\t\t\tcase \"DEFAULT_ADMIN_DELAY_CHANGE_CANCELED\": return node.newAdmin || \"\";\n\t\t\tdefault: return node.account || \"\";\n\t\t}\n\t}\n};\n/**\n* Creates an EvmIndexerClient instance for a network configuration.\n*\n* @param networkConfig - EVM network configuration (includes indexer URL)\n* @returns A new EvmIndexerClient instance\n*/\nfunction createIndexerClient(networkConfig) {\n\treturn new EvmIndexerClient(networkConfig);\n}\n\n//#endregion\n//#region src/access-control/onchain-reader.ts\nconst LOG_SYSTEM$1 = \"EvmOnChainReader\";\n/** Alias for readability within this module */\nfunction createClient(rpcUrl, viemChain) {\n\treturn createEvmPublicClient(rpcUrl, viemChain);\n}\n/**\n* Read the current ownership state from an Ownable / Ownable2Step contract.\n*\n* Calls `owner()` (required) and `pendingOwner()` (optional — only Ownable2Step).\n* If `pendingOwner()` reverts or returns the zero address, `pendingOwner` is undefined.\n* If `owner()` returns the zero address, `owner` is returned as `null` (renounced).\n*\n* @param rpcUrl - RPC endpoint URL\n* @param contractAddress - The EVM contract address (0x-prefixed)\n* @param viemChain - Optional viem Chain object for the network\n* @returns Ownership read result with owner and optional pendingOwner\n* @throws OperationFailed if the `owner()` call fails\n*/\nasync function readOwnership(rpcUrl, contractAddress, viemChain) {\n\tlogger.info(LOG_SYSTEM$1, `Reading ownership for contract ${contractAddress}`);\n\tconst client = createClient(rpcUrl, viemChain);\n\tconst address = contractAddress;\n\tlet ownerAddress;\n\ttry {\n\t\townerAddress = await client.readContract({\n\t\t\taddress,\n\t\t\tabi: OWNER_ABI,\n\t\t\tfunctionName: \"owner\"\n\t\t});\n\t} catch (error) {\n\t\tlogger.error(LOG_SYSTEM$1, `Failed to read owner() for ${contractAddress}:`, error);\n\t\tthrow new OperationFailed(`Failed to read ownership: ${error.message}`, contractAddress, \"readOwnership\", error);\n\t}\n\tconst owner = ownerAddress.toLowerCase() === ZERO_ADDRESS.toLowerCase() ? null : ownerAddress;\n\tlet pendingOwner;\n\ttry {\n\t\tconst pendingOwnerAddress = await client.readContract({\n\t\t\taddress,\n\t\t\tabi: PENDING_OWNER_ABI,\n\t\t\tfunctionName: \"pendingOwner\"\n\t\t});\n\t\tif (pendingOwnerAddress.toLowerCase() !== ZERO_ADDRESS.toLowerCase()) pendingOwner = pendingOwnerAddress;\n\t} catch {\n\t\tlogger.debug(LOG_SYSTEM$1, `No pendingOwner() on ${contractAddress} (basic Ownable)`);\n\t}\n\tlogger.debug(LOG_SYSTEM$1, `Ownership for ${contractAddress}:`, {\n\t\towner,\n\t\tpendingOwner: pendingOwner ?? \"none\"\n\t});\n\treturn {\n\t\towner,\n\t\tpendingOwner\n\t};\n}\n/**\n* Read the current default admin state from an AccessControlDefaultAdminRules contract.\n*\n* Calls `defaultAdmin()`, `pendingDefaultAdmin()`, `defaultAdminDelay()`, and\n* `pendingDefaultAdminDelay()`.\n* If `defaultAdmin()` returns the zero address, `defaultAdmin` is returned as `null` (renounced).\n* If `pendingDefaultAdmin()` returns the zero address as the new admin, no pending transfer\n* is indicated.\n*\n* @param rpcUrl - RPC endpoint URL\n* @param contractAddress - The EVM contract address (0x-prefixed)\n* @param viemChain - Optional viem Chain object for the network\n* @returns Admin read result with defaultAdmin, optional pendingDefaultAdmin and acceptSchedule\n* @throws OperationFailed if the `defaultAdmin()` call fails\n*/\nasync function getAdmin(rpcUrl, contractAddress, viemChain) {\n\tlogger.info(LOG_SYSTEM$1, `Reading admin info for contract ${contractAddress}`);\n\tconst client = createClient(rpcUrl, viemChain);\n\tconst address = contractAddress;\n\tlet adminAddress;\n\ttry {\n\t\tadminAddress = await client.readContract({\n\t\t\taddress,\n\t\t\tabi: DEFAULT_ADMIN_ABI,\n\t\t\tfunctionName: \"defaultAdmin\"\n\t\t});\n\t} catch (error) {\n\t\tlogger.error(LOG_SYSTEM$1, `Failed to read defaultAdmin() for ${contractAddress}:`, error);\n\t\tthrow new OperationFailed(`Failed to read admin info: ${error.message}`, contractAddress, \"getAdmin\", error);\n\t}\n\tconst defaultAdmin = adminAddress.toLowerCase() === ZERO_ADDRESS.toLowerCase() ? null : adminAddress;\n\tlet pendingDefaultAdmin;\n\tlet acceptSchedule;\n\ttry {\n\t\tconst [newAdmin, schedule] = await client.readContract({\n\t\t\taddress,\n\t\t\tabi: PENDING_DEFAULT_ADMIN_ABI,\n\t\t\tfunctionName: \"pendingDefaultAdmin\"\n\t\t});\n\t\tif (newAdmin.toLowerCase() !== ZERO_ADDRESS.toLowerCase()) {\n\t\t\tpendingDefaultAdmin = newAdmin;\n\t\t\tacceptSchedule = Number(schedule);\n\t\t}\n\t} catch (error) {\n\t\tlogger.warn(LOG_SYSTEM$1, `Failed to read pendingDefaultAdmin() for ${contractAddress}:`, error);\n\t}\n\tlet defaultAdminDelay;\n\ttry {\n\t\tconst delay = await client.readContract({\n\t\t\taddress,\n\t\t\tabi: DEFAULT_ADMIN_DELAY_ABI,\n\t\t\tfunctionName: \"defaultAdminDelay\"\n\t\t});\n\t\tdefaultAdminDelay = Number(delay);\n\t} catch (error) {\n\t\tlogger.warn(LOG_SYSTEM$1, `Failed to read defaultAdminDelay() for ${contractAddress}:`, error);\n\t}\n\tlet pendingDefaultAdminDelay;\n\tlet pendingDefaultAdminDelaySchedule;\n\ttry {\n\t\tconst [newDelay, schedule] = await client.readContract({\n\t\t\taddress,\n\t\t\tabi: PENDING_DEFAULT_ADMIN_DELAY_ABI,\n\t\t\tfunctionName: \"pendingDefaultAdminDelay\"\n\t\t});\n\t\tif (Number(schedule) !== 0) {\n\t\t\tpendingDefaultAdminDelay = Number(newDelay);\n\t\t\tpendingDefaultAdminDelaySchedule = Number(schedule);\n\t\t}\n\t} catch (error) {\n\t\tlogger.warn(LOG_SYSTEM$1, `Failed to read pendingDefaultAdminDelay() for ${contractAddress}:`, error);\n\t}\n\tlogger.debug(LOG_SYSTEM$1, `Admin info for ${contractAddress}:`, {\n\t\tdefaultAdmin,\n\t\tpendingDefaultAdmin: pendingDefaultAdmin ?? \"none\",\n\t\tacceptSchedule,\n\t\tdefaultAdminDelay,\n\t\tpendingDefaultAdminDelay: pendingDefaultAdminDelay ?? \"none\",\n\t\tpendingDefaultAdminDelaySchedule\n\t});\n\treturn {\n\t\tdefaultAdmin,\n\t\tpendingDefaultAdmin,\n\t\tacceptSchedule,\n\t\tdefaultAdminDelay,\n\t\tpendingDefaultAdminDelay,\n\t\tpendingDefaultAdminDelaySchedule\n\t};\n}\n/**\n* Enumerate all members of a role using AccessControlEnumerable.\n*\n* Calls `getRoleMemberCount(role)` then `getRoleMember(role, index)` for each index.\n* Throws if `getRoleMemberCount` fails (contract may not be AccessControlEnumerable).\n*\n* @param rpcUrl - RPC endpoint URL\n* @param contractAddress - The EVM contract address (0x-prefixed)\n* @param roleId - bytes32 role identifier\n* @param viemChain - Optional viem Chain object\n* @returns Array of member addresses\n* @throws OperationFailed if getRoleMemberCount fails\n*/\nasync function enumerateRoleMembers(rpcUrl, contractAddress, roleId, viemChain) {\n\tlogger.info(LOG_SYSTEM$1, `Enumerating members for role ${roleId} on ${contractAddress}`);\n\tconst client = createClient(rpcUrl, viemChain);\n\tconst address = contractAddress;\n\tlet count;\n\ttry {\n\t\tconst rawCount = await client.readContract({\n\t\t\taddress,\n\t\t\tabi: GET_ROLE_MEMBER_COUNT_ABI,\n\t\t\tfunctionName: \"getRoleMemberCount\",\n\t\t\targs: [roleId]\n\t\t});\n\t\tcount = Number(rawCount);\n\t} catch (error) {\n\t\tlogger.error(LOG_SYSTEM$1, `Failed to get role member count for ${roleId}:`, error);\n\t\tthrow new OperationFailed(`Failed to enumerate role members: ${error.message}`, contractAddress, \"enumerateRoleMembers\", error);\n\t}\n\tif (count === 0) {\n\t\tlogger.debug(LOG_SYSTEM$1, `Role ${roleId} has 0 members`);\n\t\treturn [];\n\t}\n\tconst members = [];\n\tfor (let i = 0; i < count; i++) try {\n\t\tconst member = await client.readContract({\n\t\t\taddress,\n\t\t\tabi: GET_ROLE_MEMBER_ABI,\n\t\t\tfunctionName: \"getRoleMember\",\n\t\t\targs: [roleId, BigInt(i)]\n\t\t});\n\t\tmembers.push(member);\n\t} catch (error) {\n\t\tlogger.warn(LOG_SYSTEM$1, `Failed to get role member at index ${i} for ${roleId}:`, error);\n\t}\n\tlogger.debug(LOG_SYSTEM$1, `Role ${roleId}: ${members.length} of ${count} members retrieved`);\n\treturn members;\n}\n/**\n* Read current role assignments for provided role IDs.\n*\n* For each role ID, enumerates members (if `hasEnumerableRoles` is true) or\n* returns the role with an empty members array (caller must check membership\n* via `hasRole` or indexer).\n*\n* Labels are resolved from the optional roleLabelMap (external + ABI-extracted),\n* then the well-known dictionary (DEFAULT_ADMIN_ROLE, MINTER_ROLE, etc.).\n*\n* @param rpcUrl - RPC endpoint URL\n* @param contractAddress - The EVM contract address\n* @param roleIds - Array of bytes32 role identifiers\n* @param hasEnumerableRoles - Whether the contract supports AccessControlEnumerable\n* @param viemChain - Optional viem Chain object\n* @param roleLabelMap - Optional per-contract map of hash -> label for human-readable display\n* @returns Array of role assignments\n*/\nasync function readCurrentRoles(rpcUrl, contractAddress, roleIds, hasEnumerableRoles, viemChain, roleLabelMap) {\n\tlogger.info(LOG_SYSTEM$1, `Reading ${roleIds.length} role(s) for contract ${contractAddress} (enumerable: ${hasEnumerableRoles})`);\n\tif (roleIds.length === 0) return [];\n\tconst assignments = await Promise.all(roleIds.map(async (roleId) => {\n\t\tconst role = {\n\t\t\tid: roleId,\n\t\t\tlabel: resolveRoleLabel(roleId, roleLabelMap)\n\t\t};\n\t\tif (!hasEnumerableRoles) return {\n\t\t\trole,\n\t\t\tmembers: []\n\t\t};\n\t\ttry {\n\t\t\treturn {\n\t\t\t\trole,\n\t\t\t\tmembers: await enumerateRoleMembers(rpcUrl, contractAddress, roleId, viemChain)\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tlogger.warn(LOG_SYSTEM$1, `Failed to enumerate role ${roleId}:`, error);\n\t\t\treturn {\n\t\t\t\trole,\n\t\t\t\tmembers: []\n\t\t\t};\n\t\t}\n\t}));\n\tlogger.info(LOG_SYSTEM$1, `Completed reading ${assignments.length} role(s) with ${assignments.reduce((sum, a) => sum + a.members.length, 0)} total members`);\n\treturn assignments;\n}\n/**\n* Get the current block number from the RPC endpoint.\n*\n* @param rpcUrl - RPC endpoint URL\n* @param viemChain - Optional viem Chain object\n* @returns The current block number\n* @throws OperationFailed if the call fails\n*/\nasync function getCurrentBlock(rpcUrl, viemChain) {\n\tlogger.info(LOG_SYSTEM$1, `Fetching current block from ${rpcUrl}`);\n\tconst client = createClient(rpcUrl, viemChain);\n\ttry {\n\t\tconst blockNumber = await client.getBlockNumber();\n\t\tconst block = Number(blockNumber);\n\t\tlogger.debug(LOG_SYSTEM$1, `Current block: ${block}`);\n\t\treturn block;\n\t} catch (error) {\n\t\tlogger.error(LOG_SYSTEM$1, \"Failed to get current block:\", error);\n\t\tthrow new OperationFailed(`Failed to get current block: ${error.message}`, rpcUrl, \"getCurrentBlock\", error);\n\t}\n}\n\n//#endregion\n//#region src/access-control/role-discovery.ts\nconst LOG_SYSTEM = \"EvmRoleDiscovery\";\n/** Regex: function name ends with _ROLE or Role (OpenZeppelin role constant pattern) */\nconst ROLE_CONSTANT_NAME_PATTERN = /_ROLE$|Role$/;\n/**\n* Filters contract schema functions for role constant candidates.\n*\n* A candidate must have:\n* - No inputs\n* - Single bytes32 output\n* - stateMutability view or pure\n* - Name ending with _ROLE or Role\n*\n* @param contractSchema - Parsed contract schema with functions array\n* @returns Array of ContractFunction candidates\n*/\nfunction findRoleConstantCandidates(contractSchema) {\n\treturn contractSchema.functions.filter((fn) => {\n\t\tif (fn.inputs.length !== 0) return false;\n\t\tconst outputs = fn.outputs;\n\t\tif (!outputs || outputs.length !== 1 || outputs[0].type !== \"bytes32\") return false;\n\t\tconst mutability = fn.stateMutability?.toLowerCase();\n\t\tif (mutability !== \"view\" && mutability !== \"pure\") return false;\n\t\treturn ROLE_CONSTANT_NAME_PATTERN.test(fn.name);\n\t});\n}\n/**\n* Discovers role labels by calling role constant candidates on-chain.\n*\n* For each candidate from findRoleConstantCandidates(), calls the function\n* on the contract and maps the returned bytes32 value to the function name.\n* Failed calls are skipped (graceful degradation).\n*\n* @param rpcUrl - RPC endpoint URL\n* @param contractAddress - The EVM contract address (0x-prefixed)\n* @param contractSchema - Parsed contract schema\n* @param viemChain - Optional viem Chain object\n* @returns Map of bytes32 hash (0x-prefixed, 64 hex chars) -> function name (label)\n*/\nasync function discoverRoleLabelsFromAbi(rpcUrl, contractAddress, contractSchema, viemChain) {\n\tconst candidates = findRoleConstantCandidates(contractSchema);\n\tif (candidates.length === 0) {\n\t\tlogger.debug(LOG_SYSTEM, `No role constant candidates for ${contractAddress}`);\n\t\treturn /* @__PURE__ */ new Map();\n\t}\n\tconst client = createEvmPublicClient(rpcUrl, viemChain);\n\tconst address = contractAddress;\n\tconst result = /* @__PURE__ */ new Map();\n\tconst callResults = await Promise.allSettled(candidates.map(async (fn) => {\n\t\tconst abi = [{\n\t\t\ttype: \"function\",\n\t\t\tname: fn.name,\n\t\t\tinputs: [],\n\t\t\toutputs: [{\n\t\t\t\tname: \"\",\n\t\t\t\ttype: \"bytes32\"\n\t\t\t}],\n\t\t\tstateMutability: fn.stateMutability || \"view\"\n\t\t}];\n\t\tconst value = await client.readContract({\n\t\t\taddress,\n\t\t\tabi,\n\t\t\tfunctionName: fn.name,\n\t\t\targs: []\n\t\t});\n\t\treturn {\n\t\t\tname: fn.name,\n\t\t\tvalue\n\t\t};\n\t}));\n\tfor (const settled of callResults) {\n\t\tif (settled.status === \"rejected\") {\n\t\t\tlogger.debug(LOG_SYSTEM, `Skipping role constant on ${contractAddress}: ${settled.reason.message}`);\n\t\t\tcontinue;\n\t\t}\n\t\tconst { name, value } = settled.value;\n\t\tconst raw = typeof value === \"string\" ? value.toLowerCase() : `0x${value.toString(16).padStart(64, \"0\")}`;\n\t\tconst normalizedHash = raw.startsWith(\"0x\") ? `0x${raw.slice(2).padStart(64, \"0\")}` : `0x${raw.padStart(64, \"0\")}`;\n\t\tresult.set(normalizedHash, name);\n\t\tlogger.debug(LOG_SYSTEM, `Resolved role constant ${name} -> ${normalizedHash}`);\n\t}\n\tlogger.info(LOG_SYSTEM, `Discovered ${result.size} role label(s) from ABI for ${contractAddress}`, { candidates: candidates.length });\n\treturn result;\n}\n\n//#endregion\n//#region src/access-control/validation.ts\n/**\n* EVM Access Control Input Validation\n*\n* Provides throwing validation wrappers for the access control module.\n* Reuses `isValidEvmAddress` from `../utils/validation.ts` for address checks\n* and adds bytes32 role ID validation (access-control-specific).\n*\n* All functions throw `ConfigurationInvalid` from `@openzeppelin/ui-types`\n* on failure, matching the Stellar adapter's error handling pattern.\n*\n* @module access-control/validation\n* @see research.md §R8 — EVM Address and Role Validation\n*/\n/**\n* Regex pattern for validating bytes32 hex strings.\n* Must be 0x followed by exactly 64 hex characters (case-insensitive).\n*/\nconst BYTES32_PATTERN = /^0x[0-9a-fA-F]{64}$/;\n/**\n* Validates an EVM address, throwing `ConfigurationInvalid` on failure.\n*\n* Delegates to the existing `isValidEvmAddress()` utility (which uses\n* viem's `isAddress()` under the hood). EVM does not distinguish between\n* contract and account addresses — both are 20-byte hex strings — so a\n* single validation function is sufficient.\n*\n* @param address - The EVM address to validate (contract or account)\n* @param paramName - Parameter name for error messages (e.g. 'contractAddress', 'account', 'newOwner')\n* @throws ConfigurationInvalid if the address is empty or not a valid EVM address\n*/\nfunction validateAddress(address, paramName = \"address\") {\n\tassertNonEmptyString(address, paramName);\n\tif (!isValidEvmAddress(address)) throw new ConfigurationInvalid(`Invalid EVM address: ${address}. Addresses must be 0x-prefixed, 40-character hex strings.`, address, paramName);\n}\n/**\n* Validates a role identifier as a bytes32 hex string.\n*\n* EVM AccessControl uses `bytes32` values as role identifiers, typically\n* computed as `keccak256(\"ROLE_NAME\")`. The format is `0x` followed by\n* exactly 64 hex characters (case-insensitive).\n*\n* The `DEFAULT_ADMIN_ROLE` (bytes32 zero: `0x0000...0000`) is a valid role ID.\n*\n* Returns the trimmed, lowercase-normalized role ID so callers can use the\n* sanitized value in downstream operations (e.g. transaction assembly, Set\n* deduplication, Map lookups). Normalizing to lowercase at the validation\n* boundary ensures case-insensitive deduplication across all consumers.\n*\n* @param roleId - The role identifier to validate\n* @param paramName - Optional parameter name for error messages (defaults to 'roleId')\n* @returns The trimmed, lowercase-normalized, validated role ID\n* @throws ConfigurationInvalid if the role ID is invalid\n*/\nfunction validateRoleId(roleId, paramName = \"roleId\") {\n\tassertNonEmptyString(roleId, paramName);\n\tconst trimmed = roleId.trim();\n\tif (!BYTES32_PATTERN.test(trimmed)) throw new ConfigurationInvalid(`${paramName}: Invalid bytes32 role ID: ${trimmed}. Role IDs must be 0x-prefixed, 64-character hex strings (bytes32).`, roleId, paramName);\n\treturn trimmed.toLowerCase();\n}\n/**\n* Validates an array of role identifiers.\n*\n* Each role ID is validated as a bytes32 hex string. The array is deduplicated\n* before returning. An empty array is valid (means no known role IDs).\n*\n* @param roleIds - The array of role identifiers to validate\n* @param paramName - Optional parameter name for error messages (defaults to 'roleIds')\n* @returns The validated and deduplicated array of role IDs\n* @throws ConfigurationInvalid if the input is not an array or any role ID is invalid\n*/\nfunction validateRoleIds(roleIds, paramName = \"roleIds\") {\n\tif (!Array.isArray(roleIds)) throw new ConfigurationInvalid(`${paramName} must be an array`, String(roleIds), paramName);\n\tconst validated = roleIds.map((r, i) => validateRoleId(r, `${paramName}[${i}]`));\n\treturn [...new Set(validated)];\n}\n/**\n* Asserts that a value is a non-empty string.\n*\n* @param value - The value to check\n* @param paramName - Parameter name for error messages\n* @throws ConfigurationInvalid if the value is not a non-empty string\n*/\nfunction assertNonEmptyString(value, paramName) {\n\tif (!value || typeof value !== \"string\" || value.trim() === \"\") throw new ConfigurationInvalid(`${paramName} is required and must be a non-empty string`, value, paramName);\n}\n\n//#endregion\n//#region src/access-control/service.ts\n/** Empty history result used for graceful degradation (FR-017) */\nconst EMPTY_HISTORY_RESULT = {\n\titems: [],\n\tpageInfo: { hasNextPage: false }\n};\n/**\n* EVM implementation of AccessControlService.\n*\n* This class is incrementally built across user stories. Phase 3 (US1) provides:\n* - registerContract()\n* - addKnownRoleIds()\n* - getCapabilities()\n* - dispose()\n*\n* Subsequent phases add: getOwnership, getAdminInfo, getCurrentRoles,\n* getCurrentRolesEnriched, grantRole, revokeRole, transferOwnership,\n* acceptOwnership, renounceOwnership, transferAdminRole, acceptAdminTransfer,\n* cancelAdminTransfer, changeAdminDelay, rollbackAdminDelay, renounceRole,\n* getHistory, exportSnapshot, discoverKnownRoleIds.\n*/\nvar EvmAccessControlService = class {\n\tcontractContexts = /* @__PURE__ */ new Map();\n\tnetworkConfig;\n\texecuteTransaction;\n\tindexerClient;\n\tconstructor(networkConfig, executeTransaction) {\n\t\tthis.networkConfig = networkConfig;\n\t\tthis.executeTransaction = executeTransaction;\n\t\tthis.indexerClient = createIndexerClient(networkConfig);\n\t}\n\t/**\n\t* Register a contract for access control operations.\n\t*\n\t* Validates the contract address and optional role IDs, then stores the context\n\t* in-memory. Re-registration overwrites the previous context.\n\t*\n\t* @param contractAddress - EVM address (0x-prefixed, 42 chars)\n\t* @param contractSchema - Parsed ABI as ContractSchema\n\t* @param knownRoleIds - Optional bytes32 role identifiers\n\t* @throws ConfigurationInvalid if address or role IDs are invalid\n\t*/\n\tregisterContract(contractAddress, contractSchema, knownRoleIds) {\n\t\tvalidateAddress(contractAddress, \"contractAddress\");\n\t\tconst validatedRoleIds = knownRoleIds ? validateRoleIds(knownRoleIds) : [];\n\t\tconst normalizedAddress = contractAddress.toLowerCase();\n\t\tthis.contractContexts.set(normalizedAddress, {\n\t\t\tcontractAddress: normalizedAddress,\n\t\t\tcontractSchema,\n\t\t\tknownRoleIds: validatedRoleIds,\n\t\t\tdiscoveredRoleIds: [],\n\t\t\troleDiscoveryAttempted: false,\n\t\t\tcapabilities: null,\n\t\t\troleLabelMap: /* @__PURE__ */ new Map(),\n\t\t\tabiRoleDiscoveryDone: false\n\t\t});\n\t\tlogger.debug(\"EvmAccessControlService.registerContract\", `Registered ${normalizedAddress}`, { roleCount: validatedRoleIds.length });\n\t}\n\t/**\n\t* Add additional known role IDs to a registered contract.\n\t*\n\t* Merges with existing role IDs using union with deduplication.\n\t* Accepts plain role IDs (string) or label pairs ({ id, label }) for human-readable display.\n\t* External labels are stored in context.roleLabelMap and take precedence over ABI/dictionary.\n\t*\n\t* @param contractAddress - Previously registered contract address\n\t* @param roleIds - Additional bytes32 role identifiers, or { id, label } pairs\n\t* @returns Merged array of all known role IDs\n\t* @throws ConfigurationInvalid if contract not registered or role IDs invalid\n\t*/\n\taddKnownRoleIds(contractAddress, roleIds) {\n\t\tvalidateAddress(contractAddress, \"contractAddress\");\n\t\tconst context = this.getContextOrThrow(contractAddress);\n\t\tconst validatedIds = [];\n\t\tfor (let i = 0; i < roleIds.length; i++) {\n\t\t\tconst item = roleIds[i];\n\t\t\tif (typeof item === \"string\") validatedIds.push(validateRoleId(item, `roleIds[${i}]`));\n\t\t\telse {\n\t\t\t\tvalidatedIds.push(validateRoleId(item.id, `roleIds[${i}].id`));\n\t\t\t\tcontext.roleLabelMap.set(validatedIds[validatedIds.length - 1], item.label);\n\t\t\t}\n\t\t}\n\t\tif (validatedIds.length === 0) {\n\t\t\tlogger.debug(\"EvmAccessControlService.addKnownRoleIds\", `No valid role IDs to add for ${context.contractAddress}`);\n\t\t\treturn [...context.knownRoleIds];\n\t\t}\n\t\tconst mergedRoleIds = [...new Set([...context.knownRoleIds, ...validatedIds])];\n\t\tcontext.knownRoleIds = mergedRoleIds;\n\t\tlogger.info(\"EvmAccessControlService.addKnownRoleIds\", `Added ${validatedIds.length} role ID(s) for ${context.contractAddress}`, {\n\t\t\tadded: validatedIds,\n\t\t\ttotal: mergedRoleIds.length\n\t\t});\n\t\treturn mergedRoleIds;\n\t}\n\t/**\n\t* Ensures ABI role constant discovery has been run once for this contract.\n\t* Merges discovered hash -> label into context.roleLabelMap and sets abiRoleDiscoveryDone.\n\t*/\n\tasync ensureAbiRoleLabels(context) {\n\t\tif (context.abiRoleDiscoveryDone) return;\n\t\ttry {\n\t\t\tconst discovered = await discoverRoleLabelsFromAbi(resolveRpcUrl(this.networkConfig), context.contractAddress, context.contractSchema, this.networkConfig.viemChain);\n\t\t\tfor (const [hash, label] of discovered) if (!context.roleLabelMap.has(hash)) context.roleLabelMap.set(hash, label);\n\t\t} finally {\n\t\t\tcontext.abiRoleDiscoveryDone = true;\n\t\t}\n\t}\n\t/**\n\t* Detect access control capabilities from the contract's ABI.\n\t*\n\t* Results are cached after the first call for a given contract. Also checks\n\t* indexer availability for the `supportsHistory` flag.\n\t*\n\t* @param contractAddress - Previously registered contract address\n\t* @returns Detected capabilities\n\t* @throws ConfigurationInvalid if contract not registered or address invalid\n\t*/\n\tasync getCapabilities(contractAddress) {\n\t\tvalidateAddress(contractAddress, \"contractAddress\");\n\t\tlogger.info(\"EvmAccessControlService.getCapabilities\", `Detecting capabilities for ${contractAddress}`);\n\t\tconst context = this.getContextOrThrow(contractAddress);\n\t\tif (context.capabilities !== null) {\n\t\t\tlogger.debug(\"EvmAccessControlService.getCapabilities\", `Returning cached capabilities for ${context.contractAddress}`);\n\t\t\treturn context.capabilities;\n\t\t}\n\t\tconst indexerAvailable = this.hasIndexerEndpoint();\n\t\tconst capabilities = detectAccessControlCapabilities(context.contractSchema, indexerAvailable);\n\t\tcontext.capabilities = capabilities;\n\t\tlogger.debug(\"EvmAccessControlService.getCapabilities\", \"Detected capabilities:\", {\n\t\t\thasOwnable: capabilities.hasOwnable,\n\t\t\thasTwoStepOwnable: capabilities.hasTwoStepOwnable,\n\t\t\thasAccessControl: capabilities.hasAccessControl,\n\t\t\thasTwoStepAdmin: capabilities.hasTwoStepAdmin,\n\t\t\thasEnumerableRoles: capabilities.hasEnumerableRoles,\n\t\t\tsupportsHistory: capabilities.supportsHistory\n\t\t});\n\t\treturn capabilities;\n\t}\n\t/**\n\t* Get current ownership state.\n\t*\n\t* On-chain reads: `owner()`, `pendingOwner()` (if Ownable2Step)\n\t* Indexer enrichment: pending transfer initiation timestamp/tx\n\t*\n\t* State mapping:\n\t* - owner !== zeroAddress && no pendingOwner → 'owned'\n\t* - pendingOwner set → 'pending' (expirationBlock = undefined — no expiration for EVM)\n\t* - owner === zeroAddress → 'renounced'\n\t* - Never returns 'expired' for EVM (FR-023)\n\t*\n\t* Graceful degradation (FR-017): Returns on-chain data without enrichment\n\t* when the indexer is unavailable.\n\t*\n\t* @param contractAddress - Previously registered contract address\n\t* @returns Ownership information with state classification\n\t* @throws ConfigurationInvalid if contract not registered or address invalid\n\t*/\n\tasync getOwnership(contractAddress) {\n\t\tvalidateAddress(contractAddress, \"contractAddress\");\n\t\tlogger.info(\"EvmAccessControlService.getOwnership\", `Reading ownership status for ${contractAddress}`);\n\t\tconst context = this.getContextOrThrow(contractAddress);\n\t\tif (!(context.capabilities ?? await this.getCapabilities(contractAddress)).hasOwnable) throw new OperationFailed(\"Contract does not implement the Ownable interface — no owner() function available\", contractAddress, \"getOwnership\");\n\t\tconst onChainData = await readOwnership(resolveRpcUrl(this.networkConfig), context.contractAddress, this.networkConfig.viemChain);\n\t\tif (onChainData.owner === null) {\n\t\t\tlogger.debug(\"EvmAccessControlService.getOwnership\", `Contract ${context.contractAddress} has renounced ownership`);\n\t\t\treturn {\n\t\t\t\towner: null,\n\t\t\t\tstate: \"renounced\"\n\t\t\t};\n\t\t}\n\t\tif (!onChainData.pendingOwner) {\n\t\t\tlogger.debug(\"EvmAccessControlService.getOwnership\", `Contract ${context.contractAddress} has owner with no pending transfer`);\n\t\t\treturn {\n\t\t\t\towner: onChainData.owner,\n\t\t\t\tstate: \"owned\"\n\t\t\t};\n\t\t}\n\t\tconst pendingTransfer = {\n\t\t\tpendingOwner: onChainData.pendingOwner,\n\t\t\texpirationBlock: void 0\n\t\t};\n\t\tif (await this.indexerClient.isAvailable()) try {\n\t\t\tconst enrichment = await this.indexerClient.queryPendingOwnershipTransfer(context.contractAddress);\n\t\t\tif (enrichment) {\n\t\t\t\tpendingTransfer.initiatedAt = enrichment.initiatedAt;\n\t\t\t\tpendingTransfer.initiatedTxId = enrichment.initiatedTxId;\n\t\t\t\tpendingTransfer.initiatedBlock = enrichment.initiatedBlock;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tlogger.warn(\"EvmAccessControlService.getOwnership\", `Failed to enrich ownership from indexer: ${error instanceof Error ? error.message : String(error)}`);\n\t\t}\n\t\telse logger.warn(\"EvmAccessControlService.getOwnership\", `Indexer unavailable for ${this.networkConfig.id}: pending transfer enrichment skipped`);\n\t\tlogger.debug(\"EvmAccessControlService.getOwnership\", `Contract ${context.contractAddress} has pending transfer to ${onChainData.pendingOwner}`);\n\t\treturn {\n\t\t\towner: onChainData.owner,\n\t\t\tstate: \"pending\",\n\t\t\tpendingTransfer\n\t\t};\n\t}\n\t/**\n\t* Initiate ownership transfer.\n\t*\n\t* - Ownable: single-step `transferOwnership(newOwner)` — ownership changes immediately\n\t* - Ownable2Step: `transferOwnership(newOwner)` — sets `pendingOwner`, requires `acceptOwnership()`\n\t*\n\t* The `expirationBlock` parameter is **ignored for EVM** — EVM Ownable2Step has no\n\t* expiration mechanism (FR-023). The parameter exists for API parity with Stellar.\n\t*\n\t* @param contractAddress - Previously registered contract address\n\t* @param newOwner - The new owner address\n\t* @param _expirationBlock - Ignored for EVM (no expiration). Exists for Stellar API parity.\n\t* @param executionConfig - Execution strategy configuration (EOA, Relayer, etc.)\n\t* @param onStatusChange - Optional callback for transaction status updates\n\t* @param runtimeApiKey - Optional API key for relayer execution\n\t* @returns Operation result with transaction hash\n\t* @throws ConfigurationInvalid if contract not registered or addresses invalid\n\t*/\n\tasync transferOwnership(contractAddress, newOwner, _expirationBlock, executionConfig, onStatusChange, runtimeApiKey) {\n\t\tvalidateAddress(contractAddress, \"contractAddress\");\n\t\tvalidateAddress(newOwner, \"newOwner\");\n\t\tlogger.info(\"EvmAccessControlService.transferOwnership\", `Initiating ownership transfer for ${contractAddress} to ${newOwner}`);\n\t\tconst context = this.getContextOrThrow(contractAddress);\n\t\tconst txData = assembleTransferOwnershipAction(context.contractAddress, newOwner);\n\t\tlogger.debug(\"EvmAccessControlService.transferOwnership\", `Assembled transferOwnership tx for ${context.contractAddress}`);\n\t\treturn this.executeAction(txData, executionConfig, onStatusChange, runtimeApiKey);\n\t}\n\t/**\n\t* Accept a pending ownership transfer (Ownable2Step only).\n\t*\n\t* Must be called by the pending owner. No arguments — the caller is\n\t* implicitly validated on-chain.\n\t*\n\t* @param contractAddress - Previously registered contract address\n\t* @param executionConfig - Execution strategy configuration\n\t* @param onStatusChange - Optional callback for transaction status updates\n\t* @param runtimeApiKey - Optional API key for relayer execution\n\t* @returns Operation result with transaction hash\n\t* @throws ConfigurationInvalid if contract not registered or address invalid\n\t*/\n\tasync acceptOwnership(contractAddress, executionConfig, onStatusChange, runtimeApiKey) {\n\t\tvalidateAddress(contractAddress, \"contractAddress\");\n\t\tlogger.info(\"EvmAccessControlService.acceptOwnership\", `Accepting ownership for ${contractAddress}`);\n\t\tconst context = this.getContextOrThrow(contractAddress);\n\t\tconst txData = assembleAcceptOwnershipAction(context.contractAddress);\n\t\tlogger.debug(\"EvmAccessControlService.acceptOwnership\", `Assembled acceptOwnership tx for ${context.contractAddress}`);\n\t\treturn this.executeAction(txData, executionConfig, onStatusChange, runtimeApiKey);\n\t}\n\t/**\n\t* Renounce ownership (Ownable).\n\t*\n\t* Permanently renounces ownership — after execution, `owner()` returns the zero address\n\t* and ownership queries return state `'renounced'`.\n\t*\n\t* Part of the unified `AccessControlService` interface — gated by\n\t* `hasRenounceOwnership` capability flag.\n\t*\n\t* @param contractAddress - Previously registered contract address\n\t* @param executionConfig - Execution strategy configuration\n\t* @param onStatusChange - Optional callback for transaction status updates\n\t* @param runtimeApiKey - Optional API key for relayer execution\n\t* @returns Operation result with transaction hash\n\t* @throws ConfigurationInvalid if contract not registered or address invalid\n\t*/\n\tasync renounceOwnership(contractAddress, executionConfig, onStatusChange, runtimeApiKey) {\n\t\tvalidateAddress(contractAddress, \"contractAddress\");\n\t\tlogger.info(\"EvmAccessControlService.renounceOwnership\", `Renouncing ownership for ${contractAddress}`);\n\t\tconst context = this.getContextOrThrow(contractAddress);\n\t\tconst txData = assembleRenounceOwnershipAction(context.contractAddress);\n\t\tlogger.debug(\"EvmAccessControlService.renounceOwnership\", `Assembled renounceOwnership tx for ${context.contractAddress}`);\n\t\treturn this.executeAction(txData, executionConfig, onStatusChange, runtimeApiKey);\n\t}\n\t/**\n\t* Get expiration metadata for a transfer type.\n\t*\n\t* EVM semantics:\n\t* - Ownership transfers (Ownable2Step): No expiration → mode 'none'\n\t* - Admin transfers (AccessControlDefaultAdminRules): Contract-managed accept schedule\n\t*   → mode 'contract-managed' with the accept schedule as current value\n\t*\n\t* @param contractAddress - Previously registered contract address\n\t* @param transferType - 'ownership' or 'admin'\n\t* @returns Expiration metadata for the UI\n\t*/\n\tasync getExpirationMetadata(contractAddress, transferType) {\n\t\tvalidateAddress(contractAddress, \"contractAddress\");\n\t\tif (transferType === \"ownership\") return { mode: \"none\" };\n\t\treturn {\n\t\t\tmode: \"contract-managed\",\n\t\t\tlabel: \"Accept Schedule\",\n\t\t\tunit: \"UNIX timestamp\"\n\t\t};\n\t}\n\t/**\n\t* Get current default admin state (AccessControlDefaultAdminRules).\n\t*\n\t* On-chain reads: `defaultAdmin()`, `pendingDefaultAdmin()`, `defaultAdminDelay()`\n\t* Indexer enrichment: pending transfer initiation timestamp/tx\n\t*\n\t* State mapping:\n\t* - defaultAdmin !== zeroAddress && no pending → 'active'\n\t* - pendingDefaultAdmin set → 'pending'\n\t* - defaultAdmin === zeroAddress → 'renounced'\n\t* - Never returns 'expired' for EVM (FR-023)\n\t*\n\t* For pending transfers, `acceptSchedule` maps to `expirationBlock` — this is a\n\t* **UNIX timestamp in seconds** (NOT a block number). See research.md §R5 for the\n\t* semantic divergence between Stellar and EVM.\n\t*\n\t* @param contractAddress - Previously registered contract address\n\t* @returns Admin information with state classification\n\t* @throws ConfigurationInvalid if contract not registered or address invalid\n\t*/\n\tasync getAdminInfo(contractAddress) {\n\t\tvalidateAddress(contractAddress, \"contractAddress\");\n\t\tlogger.info(\"EvmAccessControlService.getAdminInfo\", `Reading admin status for ${contractAddress}`);\n\t\tconst context = this.getContextOrThrow(contractAddress);\n\t\tif (!(context.capabilities ?? await this.getCapabilities(contractAddress)).hasTwoStepAdmin) throw new OperationFailed(\"Contract does not implement the AccessControlDefaultAdminRules interface — no defaultAdmin() function available\", contractAddress, \"getAdminInfo\");\n\t\tconst onChainData = await getAdmin(resolveRpcUrl(this.networkConfig), context.contractAddress, this.networkConfig.viemChain);\n\t\tconst delayInfo = onChainData.defaultAdminDelay != null ? {\n\t\t\tcurrentDelay: onChainData.defaultAdminDelay,\n\t\t\t...onChainData.pendingDefaultAdminDelay != null && onChainData.pendingDefaultAdminDelaySchedule != null ? { pendingDelay: {\n\t\t\t\tnewDelay: onChainData.pendingDefaultAdminDelay,\n\t\t\t\teffectAt: onChainData.pendingDefaultAdminDelaySchedule\n\t\t\t} } : {}\n\t\t} : void 0;\n\t\tif (onChainData.defaultAdmin === null) {\n\t\t\tlogger.debug(\"EvmAccessControlService.getAdminInfo\", `Contract ${context.contractAddress} has renounced admin`);\n\t\t\treturn {\n\t\t\t\tadmin: null,\n\t\t\t\tstate: \"renounced\",\n\t\t\t\tdelayInfo\n\t\t\t};\n\t\t}\n\t\tif (!onChainData.pendingDefaultAdmin) {\n\t\t\tlogger.debug(\"EvmAccessControlService.getAdminInfo\", `Contract ${context.contractAddress} has admin with no pending transfer`);\n\t\t\treturn {\n\t\t\t\tadmin: onChainData.defaultAdmin,\n\t\t\t\tstate: \"active\",\n\t\t\t\tdelayInfo\n\t\t\t};\n\t\t}\n\t\t/**\n\t\t* The `expirationBlock` field stores the `acceptSchedule` value from\n\t\t* `pendingDefaultAdmin()` — this is a UNIX timestamp (seconds since epoch),\n\t\t* NOT a block number. See research.md §R5 for semantic divergence.\n\t\t*/\n\t\tconst pendingTransfer = {\n\t\t\tpendingAdmin: onChainData.pendingDefaultAdmin,\n\t\t\texpirationBlock: onChainData.acceptSchedule\n\t\t};\n\t\tif (await this.indexerClient.isAvailable()) try {\n\t\t\tconst enrichment = await this.indexerClient.queryPendingAdminTransfer(context.contractAddress);\n\t\t\tif (enrichment) {\n\t\t\t\tpendingTransfer.initiatedAt = enrichment.initiatedAt;\n\t\t\t\tpendingTransfer.initiatedTxId = enrichment.initiatedTxId;\n\t\t\t\tpendingTransfer.initiatedBlock = enrichment.initiatedBlock;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tlogger.warn(\"EvmAccessControlService.getAdminInfo\", `Failed to enrich admin info from indexer: ${error instanceof Error ? error.message : String(error)}`);\n\t\t}\n\t\telse logger.warn(\"EvmAccessControlService.getAdminInfo\", `Indexer unavailable for ${this.networkConfig.id}: pending admin enrichment skipped`);\n\t\tlogger.debug(\"EvmAccessControlService.getAdminInfo\", `Contract ${context.contractAddress} has pending admin transfer to ${onChainData.pendingDefaultAdmin}`);\n\t\treturn {\n\t\t\tadmin: onChainData.defaultAdmin,\n\t\t\tstate: \"pending\",\n\t\t\tpendingTransfer,\n\t\t\tdelayInfo\n\t\t};\n\t}\n\t/**\n\t* Initiate default admin transfer (AccessControlDefaultAdminRules).\n\t*\n\t* Assembles `beginDefaultAdminTransfer(newAdmin)` and delegates execution.\n\t* The contract's built-in delay determines when the transfer can be accepted.\n\t*\n\t* The `expirationBlock` parameter is **ignored for EVM** — the delay is\n\t* determined by the contract's `defaultAdminDelay()`. The parameter exists\n\t* for API parity with Stellar.\n\t*\n\t* **Guard (FR-024)**: Throws `ConfigurationInvalid` if the contract does not\n\t* have the `hasTwoStepAdmin` capability.\n\t*\n\t* @param contractAddress - Previously registered contract address\n\t* @param newAdmin - The new admin address\n\t* @param _expirationBlock - Ignored for EVM. Exists for Stellar API parity.\n\t* @param executionConfig - Execution strategy configuration\n\t* @param onStatusChange - Optional callback for transaction status updates\n\t* @param runtimeApiKey - Optional API key for relayer execution\n\t* @returns Operation result with transaction hash\n\t* @throws ConfigurationInvalid if contract not registered, address invalid, or lacks hasTwoStepAdmin\n\t*/\n\tasync transferAdminRole(contractAddress, newAdmin, _expirationBlock, executionConfig, onStatusChange, runtimeApiKey) {\n\t\tvalidateAddress(contractAddress, \"contractAddress\");\n\t\tvalidateAddress(newAdmin, \"newAdmin\");\n\t\tlogger.info(\"EvmAccessControlService.transferAdminRole\", `Initiating admin transfer for ${contractAddress} to ${newAdmin}`);\n\t\tconst context = this.getContextOrThrow(contractAddress);\n\t\tawait this.ensureHasTwoStepAdmin(contractAddress);\n\t\tconst txData = assembleBeginAdminTransferAction(context.contractAddress, newAdmin);\n\t\tlogger.debug(\"EvmAccessControlService.transferAdminRole\", `Assembled beginDefaultAdminTransfer tx for ${context.contractAddress}`);\n\t\treturn this.executeAction(txData, executionConfig, onStatusChange, runtimeApiKey);\n\t}\n\t/**\n\t* Accept a pending default admin transfer (AccessControlDefaultAdminRules).\n\t*\n\t* Must be called by the pending admin after the accept schedule timestamp.\n\t* No arguments — the caller is implicitly validated on-chain.\n\t*\n\t* **Guard (FR-024)**: Throws `ConfigurationInvalid` if the contract does not\n\t* have the `hasTwoStepAdmin` capability.\n\t*\n\t* @param contractAddress - Previously registered contract address\n\t* @param executionConfig - Execution strategy configuration\n\t* @param onStatusChange - Optional callback for transaction status updates\n\t* @param runtimeApiKey - Optional API key for relayer execution\n\t* @returns Operation result with transaction hash\n\t* @throws ConfigurationInvalid if contract not registered, address invalid, or lacks hasTwoStepAdmin\n\t*/\n\tasync acceptAdminTransfer(contractAddress, executionConfig, onStatusChange, runtimeApiKey) {\n\t\tvalidateAddress(contractAddress, \"contractAddress\");\n\t\tlogger.info(\"EvmAccessControlService.acceptAdminTransfer\", `Accepting admin transfer for ${contractAddress}`);\n\t\tconst context = this.getContextOrThrow(contractAddress);\n\t\tawait this.ensureHasTwoStepAdmin(contractAddress);\n\t\tconst txData = assembleAcceptAdminTransferAction(context.contractAddress);\n\t\tlogger.debug(\"EvmAccessControlService.acceptAdminTransfer\", `Assembled acceptDefaultAdminTransfer tx for ${context.contractAddress}`);\n\t\treturn this.executeAction(txData, executionConfig, onStatusChange, runtimeApiKey);\n\t}\n\t/**\n\t* Cancel a pending default admin transfer (AccessControlDefaultAdminRules).\n\t*\n\t* Must be called by the current default admin. Cancels any pending transfer\n\t* and resets the pending admin state.\n\t*\n\t* Part of the unified `AccessControlService` interface — gated by\n\t* `hasCancelAdminTransfer` capability flag.\n\t*\n\t* **Guard (FR-024)**: Throws `ConfigurationInvalid` if the contract does not\n\t* have the `hasTwoStepAdmin` capability.\n\t*\n\t* @param contractAddress - Previously registered contract address\n\t* @param executionConfig - Execution strategy configuration\n\t* @param onStatusChange - Optional callback for transaction status updates\n\t* @param runtimeApiKey - Optional API key for relayer execution\n\t* @returns Operation result with transaction hash\n\t* @throws ConfigurationInvalid if contract not registered, address invalid, or lacks hasTwoStepAdmin\n\t*/\n\tasync cancelAdminTransfer(contractAddress, executionConfig, onStatusChange, runtimeApiKey) {\n\t\tvalidateAddress(contractAddress, \"contractAddress\");\n\t\tlogger.info(\"EvmAccessControlService.cancelAdminTransfer\", `Canceling admin transfer for ${contractAddress}`);\n\t\tconst context = this.getContextOrThrow(contractAddress);\n\t\tawait this.ensureHasTwoStepAdmin(contractAddress);\n\t\tconst txData = assembleCancelAdminTransferAction(context.contractAddress);\n\t\tlogger.debug(\"EvmAccessControlService.cancelAdminTransfer\", `Assembled cancelDefaultAdminTransfer tx for ${context.contractAddress}`);\n\t\treturn this.executeAction(txData, executionConfig, onStatusChange, runtimeApiKey);\n\t}\n\t/**\n\t* Change the default admin transfer delay (AccessControlDefaultAdminRules).\n\t*\n\t* Schedules a change to the delay period. The change itself has a delay\n\t* before it takes effect (determined by the current delay).\n\t*\n\t* Part of the unified `AccessControlService` interface — gated by\n\t* `hasAdminDelayManagement` capability flag.\n\t*\n\t* **Guard (FR-024)**: Throws `ConfigurationInvalid` if the contract does not\n\t* have the `hasTwoStepAdmin` capability.\n\t*\n\t* @param contractAddress - Previously registered contract address\n\t* @param newDelay - The new delay in seconds (uint48)\n\t* @param executionConfig - Execution strategy configuration\n\t* @param onStatusChange - Optional callback for transaction status updates\n\t* @param runtimeApiKey - Optional API key for relayer execution\n\t* @returns Operation result with transaction hash\n\t* @throws ConfigurationInvalid if contract not registered, address invalid, or lacks hasTwoStepAdmin\n\t*/\n\tasync changeAdminDelay(contractAddress, newDelay, executionConfig, onStatusChange, runtimeApiKey) {\n\t\tvalidateAddress(contractAddress, \"contractAddress\");\n\t\tlogger.info(\"EvmAccessControlService.changeAdminDelay\", `Changing admin delay for ${contractAddress} to ${newDelay}s`);\n\t\tconst context = this.getContextOrThrow(contractAddress);\n\t\tawait this.ensureHasTwoStepAdmin(contractAddress);\n\t\tconst txData = assembleChangeAdminDelayAction(context.contractAddress, newDelay);\n\t\tlogger.debug(\"EvmAccessControlService.changeAdminDelay\", `Assembled changeDefaultAdminDelay tx for ${context.contractAddress}`);\n\t\treturn this.executeAction(txData, executionConfig, onStatusChange, runtimeApiKey);\n\t}\n\t/**\n\t* Rollback a pending admin delay change (AccessControlDefaultAdminRules).\n\t*\n\t* Cancels a scheduled delay change. Must be called by the current default admin\n\t* before the delay change takes effect.\n\t*\n\t* Part of the unified `AccessControlService` interface — gated by\n\t* `hasAdminDelayManagement` capability flag.\n\t*\n\t* **Guard (FR-024)**: Throws `ConfigurationInvalid` if the contract does not\n\t* have the `hasTwoStepAdmin` capability.\n\t*\n\t* @param contractAddress - Previously registered contract address\n\t* @param executionConfig - Execution strategy configuration\n\t* @param onStatusChange - Optional callback for transaction status updates\n\t* @param runtimeApiKey - Optional API key for relayer execution\n\t* @returns Operation result with transaction hash\n\t* @throws ConfigurationInvalid if contract not registered, address invalid, or lacks hasTwoStepAdmin\n\t*/\n\tasync rollbackAdminDelay(contractAddress, executionConfig, onStatusChange, runtimeApiKey) {\n\t\tvalidateAddress(contractAddress, \"contractAddress\");\n\t\tlogger.info(\"EvmAccessControlService.rollbackAdminDelay\", `Rolling back admin delay change for ${contractAddress}`);\n\t\tconst context = this.getContextOrThrow(contractAddress);\n\t\tawait this.ensureHasTwoStepAdmin(contractAddress);\n\t\tconst txData = assembleRollbackAdminDelayAction(context.contractAddress);\n\t\tlogger.debug(\"EvmAccessControlService.rollbackAdminDelay\", `Assembled rollbackDefaultAdminDelay tx for ${context.contractAddress}`);\n\t\treturn this.executeAction(txData, executionConfig, onStatusChange, runtimeApiKey);\n\t}\n\t/**\n\t* Get current role assignments for a registered AccessControl contract.\n\t*\n\t* Strategy:\n\t* 1. If AccessControlEnumerable: enumerate on-chain via `getRoleMember()`\n\t* 2. If known role IDs available: use on-chain `readCurrentRoles()` with hasRole checks\n\t* 3. If indexer available: attempt to discover role IDs via indexer\n\t* 4. Fallback: return empty array\n\t*\n\t* The `DEFAULT_ADMIN_ROLE` (bytes32 zero) is given the label `\"DEFAULT_ADMIN_ROLE\"`.\n\t* Other roles have no label (the keccak256 hash cannot be reversed).\n\t*\n\t* **Note (FR-026)**: `DEFAULT_ADMIN_ROLE` is NOT auto-included in knownRoleIds.\n\t* Consumers must provide it explicitly or rely on indexer discovery.\n\t*\n\t* @param contractAddress - Previously registered contract address\n\t* @returns Array of role assignments with members\n\t* @throws ConfigurationInvalid if contract not registered or address invalid\n\t*/\n\tasync getCurrentRoles(contractAddress) {\n\t\tvalidateAddress(contractAddress, \"contractAddress\");\n\t\tlogger.info(\"EvmAccessControlService.getCurrentRoles\", `Reading roles for ${contractAddress}`);\n\t\tconst context = this.getContextOrThrow(contractAddress);\n\t\tawait this.ensureAbiRoleLabels(context);\n\t\tconst capabilities = await this.getCapabilities(contractAddress);\n\t\tlet roleIds = this.getMergedRoleIds(context);\n\t\tif (roleIds.length === 0) {\n\t\t\tlogger.debug(\"EvmAccessControlService.getCurrentRoles\", \"No role IDs provided, attempting discovery via indexer\");\n\t\t\troleIds = await this.attemptRoleDiscovery(context);\n\t\t}\n\t\tif (roleIds.length === 0) {\n\t\t\tlogger.warn(\"EvmAccessControlService.getCurrentRoles\", \"No role IDs available (neither provided nor discoverable), returning empty array\");\n\t\t\treturn [];\n\t\t}\n\t\tconst assignments = await readCurrentRoles(resolveRpcUrl(this.networkConfig), context.contractAddress, roleIds, capabilities.hasEnumerableRoles, this.networkConfig.viemChain, context.roleLabelMap);\n\t\tif (!capabilities.hasEnumerableRoles) {\n\t\t\tif (assignments.some((a) => a.members.length === 0)) await this.populateMembersFromIndexer(context, assignments);\n\t\t}\n\t\tlogger.debug(\"EvmAccessControlService.getCurrentRoles\", `Retrieved ${assignments.length} role assignment(s) with ${assignments.reduce((sum, a) => sum + a.members.length, 0)} total member(s) for ${context.contractAddress}`);\n\t\treturn assignments;\n\t}\n\t/**\n\t* Get enriched role assignments with grant metadata from the indexer.\n\t*\n\t* Builds on `getCurrentRoles()` and enriches each member with grant timestamp,\n\t* transaction ID, and block number from the indexer. Falls back to unenriched\n\t* data if the indexer is unavailable (graceful degradation per FR-017).\n\t*\n\t* The `grantedLedger` field in `EnrichedRoleMember` stores an EVM **block number**\n\t* despite its Stellar-originated name. This is a consequence of the unified type\n\t* design — see data-model.md §6.\n\t*\n\t* @param contractAddress - Previously registered contract address\n\t* @returns Array of enriched role assignments\n\t* @throws ConfigurationInvalid if contract not registered or address invalid\n\t*/\n\tasync getCurrentRolesEnriched(contractAddress) {\n\t\tvalidateAddress(contractAddress, \"contractAddress\");\n\t\tlogger.info(\"EvmAccessControlService.getCurrentRolesEnriched\", `Reading enriched roles for ${contractAddress}`);\n\t\tconst currentRoles = await this.getCurrentRoles(contractAddress);\n\t\tif (currentRoles.length === 0) return [];\n\t\tif (!await this.indexerClient.isAvailable()) {\n\t\t\tlogger.debug(\"EvmAccessControlService.getCurrentRolesEnriched\", \"Indexer not available, returning roles without timestamps\");\n\t\t\treturn this.convertToEnrichedWithoutTimestamps(currentRoles);\n\t\t}\n\t\ttry {\n\t\t\tconst context = this.getContextOrThrow(contractAddress);\n\t\t\tconst roleIds = currentRoles.map((ra) => ra.role.id);\n\t\t\tconst grantMap = await this.indexerClient.queryLatestGrants(context.contractAddress, roleIds);\n\t\t\tif (!grantMap) {\n\t\t\t\tlogger.warn(\"EvmAccessControlService.getCurrentRolesEnriched\", \"Indexer returned null for grant data, returning without enrichment\");\n\t\t\t\treturn this.convertToEnrichedWithoutTimestamps(currentRoles);\n\t\t\t}\n\t\t\tconst grantsByRole = /* @__PURE__ */ new Map();\n\t\t\tfor (const grant of grantMap.values()) {\n\t\t\t\tconst key = grant.role.toLowerCase();\n\t\t\t\tconst existing = grantsByRole.get(key) ?? [];\n\t\t\t\texisting.push(grant);\n\t\t\t\tgrantsByRole.set(key, existing);\n\t\t\t}\n\t\t\tconst enriched = currentRoles.map((roleAssignment) => {\n\t\t\t\tconst roleIdLower = roleAssignment.role.id.toLowerCase();\n\t\t\t\tif (roleAssignment.members.length === 0) {\n\t\t\t\t\tconst indexerGrants = grantsByRole.get(roleIdLower) ?? [];\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: roleAssignment.role,\n\t\t\t\t\t\tmembers: indexerGrants.map((grant) => ({\n\t\t\t\t\t\t\taddress: grant.account,\n\t\t\t\t\t\t\tgrantedAt: grant.grantedAt,\n\t\t\t\t\t\t\tgrantedTxId: grant.txHash\n\t\t\t\t\t\t}))\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\trole: roleAssignment.role,\n\t\t\t\t\tmembers: roleAssignment.members.map((memberAddress) => {\n\t\t\t\t\t\tconst grantInfo = grantMap.get(grantMapKey(roleAssignment.role.id, memberAddress));\n\t\t\t\t\t\tconst member = { address: memberAddress };\n\t\t\t\t\t\tif (grantInfo) {\n\t\t\t\t\t\t\tmember.grantedAt = grantInfo.grantedAt;\n\t\t\t\t\t\t\tmember.grantedTxId = grantInfo.txHash;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn member;\n\t\t\t\t\t})\n\t\t\t\t};\n\t\t\t});\n\t\t\tconst totalMembers = enriched.reduce((sum, a) => sum + a.members.length, 0);\n\t\t\tlogger.debug(\"EvmAccessControlService.getCurrentRolesEnriched\", `Enriched ${enriched.length} role(s) with ${totalMembers} total member(s)`);\n\t\t\treturn enriched;\n\t\t} catch (error) {\n\t\t\tlogger.warn(\"EvmAccessControlService.getCurrentRolesEnriched\", `Failed to enrich roles from indexer: ${error instanceof Error ? error.message : String(error)}`);\n\t\t\treturn this.convertToEnrichedWithoutTimestamps(currentRoles);\n\t\t}\n\t}\n\t/**\n\t* Grant a role to an account.\n\t*\n\t* Assembles `grantRole(bytes32 role, address account)` and delegates execution.\n\t* Must be called by an account with the role's admin role (typically DEFAULT_ADMIN_ROLE).\n\t*\n\t* @param contractAddress - Previously registered contract address\n\t* @param roleId - The bytes32 role identifier to grant\n\t* @param account - The account to grant the role to\n\t* @param executionConfig - Execution strategy configuration\n\t* @param onStatusChange - Optional callback for transaction status updates\n\t* @param runtimeApiKey - Optional API key for relayer execution\n\t* @returns Operation result with transaction hash\n\t* @throws ConfigurationInvalid if contract not registered, addresses invalid, or role ID invalid\n\t*/\n\tasync grantRole(contractAddress, roleId, account, executionConfig, onStatusChange, runtimeApiKey) {\n\t\tvalidateAddress(contractAddress, \"contractAddress\");\n\t\tconst validatedRoleId = validateRoleId(roleId, \"roleId\");\n\t\tvalidateAddress(account, \"account\");\n\t\tlogger.info(\"EvmAccessControlService.grantRole\", `Granting role ${validatedRoleId} to ${account} on ${contractAddress}`);\n\t\tconst context = this.getContextOrThrow(contractAddress);\n\t\tconst txData = assembleGrantRoleAction(context.contractAddress, validatedRoleId, account);\n\t\tlogger.debug(\"EvmAccessControlService.grantRole\", `Assembled grantRole tx for ${context.contractAddress}`);\n\t\treturn this.executeAction(txData, executionConfig, onStatusChange, runtimeApiKey);\n\t}\n\t/**\n\t* Revoke a role from an account.\n\t*\n\t* Assembles `revokeRole(bytes32 role, address account)` and delegates execution.\n\t* Must be called by an account with the role's admin role.\n\t*\n\t* @param contractAddress - Previously registered contract address\n\t* @param roleId - The bytes32 role identifier to revoke\n\t* @param account - The account to revoke the role from\n\t* @param executionConfig - Execution strategy configuration\n\t* @param onStatusChange - Optional callback for transaction status updates\n\t* @param runtimeApiKey - Optional API key for relayer execution\n\t* @returns Operation result with transaction hash\n\t* @throws ConfigurationInvalid if contract not registered, addresses invalid, or role ID invalid\n\t*/\n\tasync revokeRole(contractAddress, roleId, account, executionConfig, onStatusChange, runtimeApiKey) {\n\t\tvalidateAddress(contractAddress, \"contractAddress\");\n\t\tconst validatedRoleId = validateRoleId(roleId, \"roleId\");\n\t\tvalidateAddress(account, \"account\");\n\t\tlogger.info(\"EvmAccessControlService.revokeRole\", `Revoking role ${validatedRoleId} from ${account} on ${contractAddress}`);\n\t\tconst context = this.getContextOrThrow(contractAddress);\n\t\tconst txData = assembleRevokeRoleAction(context.contractAddress, validatedRoleId, account);\n\t\tlogger.debug(\"EvmAccessControlService.revokeRole\", `Assembled revokeRole tx for ${context.contractAddress}`);\n\t\treturn this.executeAction(txData, executionConfig, onStatusChange, runtimeApiKey);\n\t}\n\t/**\n\t* Renounce own role.\n\t*\n\t* Assembles `renounceRole(bytes32 role, address callerConfirmation)` and delegates execution.\n\t* The `account` parameter acts as a caller confirmation — on-chain, the contract verifies\n\t* it matches `msg.sender` to prevent accidental renouncement.\n\t*\n\t* Part of the unified `AccessControlService` interface — gated by\n\t* `hasRenounceRole` capability flag.\n\t*\n\t* @param contractAddress - Previously registered contract address\n\t* @param roleId - The bytes32 role identifier to renounce\n\t* @param account - The caller's address for confirmation (must match msg.sender on-chain)\n\t* @param executionConfig - Execution strategy configuration\n\t* @param onStatusChange - Optional callback for transaction status updates\n\t* @param runtimeApiKey - Optional API key for relayer execution\n\t* @returns Operation result with transaction hash\n\t* @throws ConfigurationInvalid if contract not registered, addresses invalid, or role ID invalid\n\t*/\n\tasync renounceRole(contractAddress, roleId, account, executionConfig, onStatusChange, runtimeApiKey) {\n\t\tvalidateAddress(contractAddress, \"contractAddress\");\n\t\tconst validatedRoleId = validateRoleId(roleId, \"roleId\");\n\t\tvalidateAddress(account, \"account\");\n\t\tlogger.info(\"EvmAccessControlService.renounceRole\", `Renouncing role ${validatedRoleId} for ${account} on ${contractAddress}`);\n\t\tconst context = this.getContextOrThrow(contractAddress);\n\t\tconst txData = assembleRenounceRoleAction(context.contractAddress, validatedRoleId, account);\n\t\tlogger.debug(\"EvmAccessControlService.renounceRole\", `Assembled renounceRole tx for ${context.contractAddress}`);\n\t\treturn this.executeAction(txData, executionConfig, onStatusChange, runtimeApiKey);\n\t}\n\t/**\n\t* Query historical access control events from the indexer.\n\t*\n\t* Delegates to the indexer client's `queryHistory()` with filter/pagination options.\n\t* Supports filtering by: role, account, event type, time range, and pagination.\n\t*\n\t* **Graceful degradation (FR-017)**: Returns an empty `PaginatedHistoryResult`\n\t* (`{ items: [], pageInfo: { hasNextPage: false } }`) when:\n\t* - The indexer is unavailable\n\t* - The indexer query returns null\n\t* - The indexer query throws an error\n\t*\n\t* @param contractAddress - Previously registered contract address\n\t* @param options - Optional filtering and pagination options\n\t* @returns Paginated history result\n\t* @throws ConfigurationInvalid if contract not registered or address invalid\n\t*/\n\tasync getHistory(contractAddress, options) {\n\t\tvalidateAddress(contractAddress, \"contractAddress\");\n\t\tlogger.info(\"EvmAccessControlService.getHistory\", `Querying history for ${contractAddress}`);\n\t\tconst context = this.getContextOrThrow(contractAddress);\n\t\tawait this.ensureAbiRoleLabels(context);\n\t\tif (!await this.indexerClient.isAvailable()) {\n\t\t\tlogger.warn(\"EvmAccessControlService.getHistory\", `Indexer unavailable for ${this.networkConfig.id}: returning empty history`);\n\t\t\treturn EMPTY_HISTORY_RESULT;\n\t\t}\n\t\ttry {\n\t\t\tconst result = await this.indexerClient.queryHistory(context.contractAddress, options, context.roleLabelMap);\n\t\t\tif (!result) {\n\t\t\t\tlogger.warn(\"EvmAccessControlService.getHistory\", `Indexer returned null for history query on ${context.contractAddress}`);\n\t\t\t\treturn EMPTY_HISTORY_RESULT;\n\t\t\t}\n\t\t\tlogger.debug(\"EvmAccessControlService.getHistory\", `Retrieved ${result.items.length} history event(s) for ${context.contractAddress}`);\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\tlogger.warn(\"EvmAccessControlService.getHistory\", `Failed to query history: ${error instanceof Error ? error.message : String(error)}`);\n\t\t\treturn EMPTY_HISTORY_RESULT;\n\t\t}\n\t}\n\t/**\n\t* Export a point-in-time snapshot of the contract's access control state.\n\t*\n\t* Combines `getCurrentRoles()` + `getOwnership()` into a unified `AccessSnapshot`.\n\t* Ownership is omitted if the contract does not support Ownable (try/catch).\n\t* Roles default to an empty array if the read fails.\n\t*\n\t* **Known limitation**: The unified `AccessSnapshot` type does not include `adminInfo`.\n\t* Admin information is accessible separately via `getAdminInfo()`. If a future\n\t* `@openzeppelin/ui-types` update adds `adminInfo` to `AccessSnapshot`, this method\n\t* should be updated to populate it.\n\t*\n\t* @param contractAddress - Previously registered contract address\n\t* @returns Access control snapshot with roles and optional ownership\n\t* @throws ConfigurationInvalid if contract not registered or address invalid\n\t* @throws OperationFailed if the snapshot structure fails validation\n\t*/\n\tasync exportSnapshot(contractAddress) {\n\t\tvalidateAddress(contractAddress, \"contractAddress\");\n\t\tlogger.info(\"EvmAccessControlService.exportSnapshot\", `Exporting snapshot for ${contractAddress}`);\n\t\tconst context = this.getContextOrThrow(contractAddress);\n\t\tlet ownership;\n\t\ttry {\n\t\t\townership = await this.getOwnership(context.contractAddress);\n\t\t} catch (error) {\n\t\t\tlogger.debug(\"EvmAccessControlService.exportSnapshot\", `Ownership not available: ${error instanceof Error ? error.message : String(error)}`);\n\t\t}\n\t\tlet roles = [];\n\t\ttry {\n\t\t\troles = await this.getCurrentRoles(context.contractAddress);\n\t\t} catch (error) {\n\t\t\tlogger.debug(\"EvmAccessControlService.exportSnapshot\", `Roles not available: ${error instanceof Error ? error.message : String(error)}`);\n\t\t}\n\t\tconst snapshot = {\n\t\t\troles,\n\t\t\townership\n\t\t};\n\t\tif (!validateSnapshot(snapshot)) {\n\t\t\tconst errorMsg = `Invalid snapshot structure for contract ${context.contractAddress}`;\n\t\t\tlogger.error(\"EvmAccessControlService.exportSnapshot\", errorMsg);\n\t\t\tthrow new OperationFailed(errorMsg, context.contractAddress, \"exportSnapshot\");\n\t\t}\n\t\tlogger.debug(\"EvmAccessControlService.exportSnapshot\", \"Snapshot created and validated:\", {\n\t\t\thasOwnership: !!ownership?.owner,\n\t\t\troleCount: roles.length,\n\t\t\ttotalMembers: roles.reduce((sum, r) => sum + r.members.length, 0)\n\t\t});\n\t\treturn snapshot;\n\t}\n\t/**\n\t* Discover role IDs from the indexer's historical events.\n\t*\n\t* Queries the indexer for all unique role IDs that have appeared in events\n\t* for the given contract. Results are cached in the contract context — subsequent\n\t* calls return the cached value without re-querying (`roleDiscoveryAttempted` flag).\n\t*\n\t* When `knownRoleIds` were explicitly provided at registration, they are preserved\n\t* and merged with any newly discovered roles.\n\t*\n\t* **Graceful degradation (FR-017)**: Returns an empty array when:\n\t* - The indexer is unavailable\n\t* - The indexer query returns null\n\t* - The indexer query throws an error\n\t*\n\t* @param contractAddress - Previously registered contract address\n\t* @returns Array of known + discovered role IDs (deduplicated)\n\t* @throws ConfigurationInvalid if contract not registered or address invalid\n\t*/\n\tasync discoverKnownRoleIds(contractAddress) {\n\t\tvalidateAddress(contractAddress, \"contractAddress\");\n\t\tlogger.info(\"EvmAccessControlService.discoverKnownRoleIds\", `Discovering role IDs for ${contractAddress}`);\n\t\tconst context = this.getContextOrThrow(contractAddress);\n\t\tif (context.roleDiscoveryAttempted) {\n\t\t\tlogger.debug(\"EvmAccessControlService.discoverKnownRoleIds\", `Returning cached discovery result for ${context.contractAddress}`);\n\t\t\treturn this.getMergedRoleIds(context);\n\t\t}\n\t\tcontext.roleDiscoveryAttempted = true;\n\t\tif (!await this.indexerClient.isAvailable()) {\n\t\t\tlogger.warn(\"EvmAccessControlService.discoverKnownRoleIds\", `Indexer unavailable for ${this.networkConfig.id}: role discovery skipped`);\n\t\t\treturn this.getMergedRoleIds(context);\n\t\t}\n\t\ttry {\n\t\t\tconst discoveredRoles = await this.indexerClient.discoverRoleIds(context.contractAddress);\n\t\t\tif (discoveredRoles && discoveredRoles.length > 0) {\n\t\t\t\tcontext.discoveredRoleIds = discoveredRoles;\n\t\t\t\tlogger.info(\"EvmAccessControlService.discoverKnownRoleIds\", `Discovered ${discoveredRoles.length} role(s) for ${context.contractAddress}`);\n\t\t\t} else logger.debug(\"EvmAccessControlService.discoverKnownRoleIds\", `No roles discovered for ${context.contractAddress}`);\n\t\t} catch (error) {\n\t\t\tlogger.warn(\"EvmAccessControlService.discoverKnownRoleIds\", `Failed to discover roles: ${error instanceof Error ? error.message : String(error)}`);\n\t\t}\n\t\treturn this.getMergedRoleIds(context);\n\t}\n\t/**\n\t* Clean up resources — clear all contract contexts and indexer resources.\n\t*\n\t* Safe to call multiple times.\n\t*/\n\tdispose() {\n\t\tthis.contractContexts.clear();\n\t\tlogger.debug(\"EvmAccessControlService.dispose\", \"Service disposed\");\n\t}\n\t/**\n\t* Retrieves the context for a registered contract, throwing if not found.\n\t*\n\t* @param contractAddress - Contract address (will be normalized)\n\t* @returns The contract context\n\t* @throws ConfigurationInvalid if the contract is not registered\n\t*/\n\tgetContextOrThrow(contractAddress) {\n\t\tconst normalizedAddress = contractAddress.toLowerCase();\n\t\tconst context = this.contractContexts.get(normalizedAddress);\n\t\tif (!context) throw new ConfigurationInvalid(\"Contract not registered. Call registerContract() first.\", contractAddress, \"contractAddress\");\n\t\treturn context;\n\t}\n\t/**\n\t* Checks whether an indexer endpoint is configured for this network.\n\t*\n\t* Uses the config precedence: `accessControlIndexerUrl` on the network config.\n\t*/\n\thasIndexerEndpoint() {\n\t\treturn !!this.networkConfig.accessControlIndexerUrl;\n\t}\n\t/**\n\t* Guards admin operations — ensures the contract has `hasTwoStepAdmin` capability.\n\t*\n\t* Throws `ConfigurationInvalid` if the contract does not support\n\t* AccessControlDefaultAdminRules (FR-024). This prevents any on-chain\n\t* interaction with incompatible contracts.\n\t*\n\t* @param contractAddress - The contract address to check\n\t* @throws ConfigurationInvalid if the contract lacks hasTwoStepAdmin capability\n\t*/\n\tasync ensureHasTwoStepAdmin(contractAddress) {\n\t\tif (!(await this.getCapabilities(contractAddress)).hasTwoStepAdmin) throw new ConfigurationInvalid(\"Contract does not support AccessControlDefaultAdminRules (hasTwoStepAdmin is false). Admin operations require a contract with the DefaultAdminRules pattern.\", contractAddress, \"contractAddress\");\n\t}\n\t/**\n\t* Returns the union of known + discovered role IDs for a context.\n\t* Deduplicates the combined set.\n\t*/\n\tgetMergedRoleIds(context) {\n\t\treturn [...new Set([...context.knownRoleIds, ...context.discoveredRoleIds])];\n\t}\n\t/**\n\t* Attempt to discover role IDs via the indexer.\n\t*\n\t* Delegates to the indexer client's `discoverRoleIds()`. Results are cached\n\t* in the context's `discoveredRoleIds` and the `roleDiscoveryAttempted` flag\n\t* prevents retries on failure.\n\t*\n\t* @internal\n\t*/\n\tasync attemptRoleDiscovery(context) {\n\t\tif (context.roleDiscoveryAttempted) return this.getMergedRoleIds(context);\n\t\tcontext.roleDiscoveryAttempted = true;\n\t\tif (!await this.indexerClient.isAvailable()) return this.getMergedRoleIds(context);\n\t\ttry {\n\t\t\tconst discoveredRoles = await this.indexerClient.discoverRoleIds(context.contractAddress);\n\t\t\tif (discoveredRoles && discoveredRoles.length > 0) {\n\t\t\t\tcontext.discoveredRoleIds = discoveredRoles;\n\t\t\t\tlogger.info(\"EvmAccessControlService.attemptRoleDiscovery\", `Auto-discovered ${discoveredRoles.length} role(s) for ${context.contractAddress}`);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tlogger.warn(\"EvmAccessControlService.attemptRoleDiscovery\", `Role discovery failed: ${error instanceof Error ? error.message : String(error)}`);\n\t\t}\n\t\treturn this.getMergedRoleIds(context);\n\t}\n\t/**\n\t* Populate empty member arrays from indexer grant data (non-enumerable contracts).\n\t*\n\t* For contracts without `AccessControlEnumerable`, on-chain reads cannot enumerate\n\t* members. This method queries the indexer's `roleMemberships` to discover who holds\n\t* each role, mutating the `assignments` array in place.\n\t*\n\t* Graceful degradation: if the indexer is unavailable or the query fails,\n\t* members stay empty — no error is thrown.\n\t*\n\t* @internal\n\t*/\n\tasync populateMembersFromIndexer(context, assignments) {\n\t\tif (!await this.indexerClient.isAvailable()) return;\n\t\ttry {\n\t\t\tconst roleIds = assignments.map((a) => a.role.id);\n\t\t\tconst grantMap = await this.indexerClient.queryLatestGrants(context.contractAddress, roleIds);\n\t\t\tif (!grantMap || grantMap.size === 0) return;\n\t\t\tconst membersByRole = /* @__PURE__ */ new Map();\n\t\t\tfor (const grant of grantMap.values()) {\n\t\t\t\tconst key = grant.role.toLowerCase();\n\t\t\t\tconst existing = membersByRole.get(key) ?? [];\n\t\t\t\texisting.push(grant.account);\n\t\t\t\tmembersByRole.set(key, existing);\n\t\t\t}\n\t\t\tfor (const assignment of assignments) if (assignment.members.length === 0) {\n\t\t\t\tconst indexerMembers = membersByRole.get(assignment.role.id.toLowerCase());\n\t\t\t\tif (indexerMembers && indexerMembers.length > 0) assignment.members = indexerMembers;\n\t\t\t}\n\t\t\tconst totalPopulated = assignments.reduce((sum, a) => sum + a.members.length, 0);\n\t\t\tlogger.info(\"EvmAccessControlService.populateMembersFromIndexer\", `Populated ${totalPopulated} member(s) from indexer for ${context.contractAddress}`);\n\t\t} catch (error) {\n\t\t\tlogger.warn(\"EvmAccessControlService.populateMembersFromIndexer\", `Failed to populate members from indexer: ${error instanceof Error ? error.message : String(error)}`);\n\t\t}\n\t}\n\t/**\n\t* Converts RoleAssignment[] to EnrichedRoleAssignment[] without timestamps.\n\t*\n\t* Used for graceful degradation when the indexer is unavailable.\n\t* Each member gets an `EnrichedRoleMember` with only the `address` field populated.\n\t*/\n\tconvertToEnrichedWithoutTimestamps(assignments) {\n\t\treturn assignments.map((ra) => ({\n\t\t\trole: ra.role,\n\t\t\tmembers: ra.members.map((memberAddress) => ({ address: memberAddress }))\n\t\t}));\n\t}\n\t/**\n\t* Delegates transaction execution to the injected callback.\n\t* Single entry point for all write operations (Phase 6+).\n\t*\n\t* @internal\n\t*/\n\tasync executeAction(txData, executionConfig, onStatusChange, runtimeApiKey) {\n\t\treturn this.executeTransaction(txData, executionConfig, onStatusChange, runtimeApiKey);\n\t}\n};\n/**\n* Creates an EvmAccessControlService instance.\n*\n* @param networkConfig - EVM network configuration (includes indexer URL)\n* @param executeTransaction - Callback for transaction execution (provided by runtime composition)\n* @returns A new EvmAccessControlService instance\n*/\nfunction createEvmAccessControlService(networkConfig, executeTransaction) {\n\treturn new EvmAccessControlService(networkConfig, executeTransaction);\n}\n\n//#endregion\n//#region src/capabilities/access-control.ts\nfunction createAccessControl(config, options) {\n\tconst networkConfig = asTypedEvmNetworkConfig(config);\n\tconst service = createEvmAccessControlService(networkConfig, async (transactionData, executionConfig, onStatusChange, runtimeApiKey) => {\n\t\treturn { id: (await options.signAndBroadcast(transactionData, executionConfig, onStatusChange ?? (() => {}), runtimeApiKey)).txHash };\n\t});\n\treturn guardRuntimeCapability(service, networkConfig, \"accessControl\", () => service.dispose(), \"subscription\");\n}\n\n//#endregion\nexport { assembleGrantRoleAction as C, assembleRollbackAdminDelayAction as D, assembleRevokeRoleAction as E, assembleTransferOwnershipAction as O, assembleChangeAdminDelayAction as S, assembleRenounceRoleAction as T, ZERO_ADDRESS as _, validateRoleId as a, assembleBeginAdminTransferAction as b, getCurrentBlock as c, EvmIndexerClient as d, createIndexerClient as f, DEFAULT_ADMIN_ROLE_LABEL as g, DEFAULT_ADMIN_ROLE as h, validateAddress as i, readCurrentRoles as l, validateAccessControlSupport as m, EvmAccessControlService as n, validateRoleIds as o, detectAccessControlCapabilities as p, createEvmAccessControlService as r, getAdmin as s, createAccessControl as t, readOwnership as u, assembleAcceptAdminTransferAction as v, assembleRenounceOwnershipAction as w, assembleCancelAdminTransferAction as x, assembleAcceptOwnershipAction as y };\n//# sourceMappingURL=access-control-BA74EeRO.mjs.map"],"mappings":"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"}