npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

viem-oz-access-control

v1.0.0-beta.1

Published

Viem extensions for OpenZeppelin AccessControl and DefaultAdminRules contracts

Readme

viem-oz-access-control

Viem extensions for OpenZeppelin AccessControl and DefaultAdminRules contracts

NPM version Package size Follow Hemi on X

Installation

Install viem and viem-oz-access-control as dependencies:

npm install viem viem-oz-access-control

Methods

This package provides ESM-friendly helpers for interacting with OpenZeppelin AccessControl contracts using viem.

All the methods are named after the Solidity functions. The ABIs target OpenZeppelin Contracts v5.x, and every entry matches the compiled output of AccessControl and AccessControlDefaultAdminRules.

AccessControlDefaultAdminRules extends AccessControl, so this package covers both.

acceptDefaultAdminTransfer

Completes a default admin transfer. Only the pending admin can call it, and only after the schedule passes. DefaultAdminRules only. View docs

acceptDefaultAdminTransfer(client, { address });
  • client: Client — from viem — (required)
  • address: Address — AccessControl contract address (required)

Example:

import { acceptDefaultAdminTransfer } from "viem-oz-access-control/actions";
const hash = await acceptDefaultAdminTransfer(client, {
  address: "0x1234567891234567891234567891234567891234",
});

beginDefaultAdminTransfer

Starts a default admin transfer to newAdmin. Only the current default admin can call it. The new admin must accept it after the delay passes. DefaultAdminRules only. View docs

beginDefaultAdminTransfer(client, { address, newAdmin });
  • client: Client — from viem — (required)
  • address: Address — AccessControl contract address (required)
  • newAdmin: Address — Address that will become the new default admin (required)

Example:

import { beginDefaultAdminTransfer } from "viem-oz-access-control/actions";
const hash = await beginDefaultAdminTransfer(client, {
  address: "0x1234567891234567891234567891234567891234",
  newAdmin: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd",
});

cancelDefaultAdminTransfer

Cancels a scheduled default admin transfer. Only the current default admin can call it. DefaultAdminRules only. View docs

cancelDefaultAdminTransfer(client, { address });
  • client: Client — from viem — (required)
  • address: Address — AccessControl contract address (required)

Example:

import { cancelDefaultAdminTransfer } from "viem-oz-access-control/actions";
const hash = await cancelDefaultAdminTransfer(client, {
  address: "0x1234567891234567891234567891234567891234",
});

changeDefaultAdminDelay

Schedules a new delay for default admin transfers. Only the current default admin can call it. DefaultAdminRules only. View docs

changeDefaultAdminDelay(client, { address, newDelay });
  • client: Client — from viem — (required)
  • address: Address — AccessControl contract address (required)
  • newDelay: number — New delay in seconds. The contract type is uint48, so viem uses a number (required)

Example:

import { changeDefaultAdminDelay } from "viem-oz-access-control/actions";
const hash = await changeDefaultAdminDelay(client, {
  address: "0x1234567891234567891234567891234567891234",
  newDelay: 86400, // 1 day
});

defaultAdmin

Returns the address that holds DEFAULT_ADMIN_ROLE. DefaultAdminRules only. View docs

defaultAdmin(client, { address });
  • client: Client — from viem — (required)
  • address: Address — AccessControl contract address (required)

Example:

import { defaultAdmin } from "viem-oz-access-control/actions";
const admin = await defaultAdmin(client, {
  address: "0x1234567891234567891234567891234567891234",
});

defaultAdminDelay

Returns the delay, in seconds, between the start and the acceptance of a default admin transfer. DefaultAdminRules only. View docs

defaultAdminDelay(client, { address });
  • client: Client — from viem — (required)
  • address: Address — AccessControl contract address (required)

Example:

import { defaultAdminDelay } from "viem-oz-access-control/actions";
const delay = await defaultAdminDelay(client, {
  address: "0x1234567891234567891234567891234567891234",
});

defaultAdminDelayIncreaseWait

Returns the maximum wait, in seconds, applied when the delay increases. It defaults to 5 days. DefaultAdminRules only. View docs

defaultAdminDelayIncreaseWait(client, { address });
  • client: Client — from viem — (required)
  • address: Address — AccessControl contract address (required)

Example:

import { defaultAdminDelayIncreaseWait } from "viem-oz-access-control/actions";
const wait = await defaultAdminDelayIncreaseWait(client, {
  address: "0x1234567891234567891234567891234567891234",
});

getRoleAdmin

Returns the role that administers the given role. Holders of the admin role can grant and revoke it. View docs

getRoleAdmin(client, { address, role });
  • client: Client — from viem — (required)
  • address: Address — AccessControl contract address (required)
  • role: Hash — Role identifier, 32 bytes. Use roleId to build it (required)

Example:

import { roleId } from "viem-oz-access-control";
import { getRoleAdmin } from "viem-oz-access-control/actions";
const adminRole = await getRoleAdmin(client, {
  address: "0x1234567891234567891234567891234567891234",
  role: roleId("KEEPER_ROLE"),
});

grantRole

Grants a role to an account. The caller must hold the admin role of that role. On a DefaultAdminRules contract this reverts for DEFAULT_ADMIN_ROLE; use beginDefaultAdminTransfer instead. View docs

grantRole(client, { account, address, role });
  • client: Client — from viem — (required)
  • account: Address — Address that receives the role (required)
  • address: Address — AccessControl contract address (required)
  • role: Hash — Role identifier, 32 bytes (required)

Example:

import { roleId } from "viem-oz-access-control";
import { grantRole } from "viem-oz-access-control/actions";
const hash = await grantRole(client, {
  account: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd",
  address: "0x1234567891234567891234567891234567891234",
  role: roleId("KEEPER_ROLE"),
});

hasRole

Returns true if the account holds the role. View docs

hasRole(client, { account, address, role });
  • client: Client — from viem — (required)
  • account: Address — Address to check (required)
  • address: Address — AccessControl contract address (required)
  • role: Hash — Role identifier, 32 bytes (required)

Example:

import { roleId } from "viem-oz-access-control";
import { hasRole } from "viem-oz-access-control/actions";
const isKeeper = await hasRole(client, {
  account: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd",
  address: "0x1234567891234567891234567891234567891234",
  role: roleId("KEEPER_ROLE"),
});

pendingDefaultAdmin

Returns the pending default admin and the timestamp at which it can accept the transfer. A zero acceptSchedule means that no transfer is pending. A zero newAdmin means that the default admin is being renounced. DefaultAdminRules only. View docs

pendingDefaultAdmin(client, { address });
  • client: Client — from viem — (required)
  • address: Address — AccessControl contract address (required)

Example:

import { pendingDefaultAdmin } from "viem-oz-access-control/actions";
const [newAdmin, acceptSchedule] = await pendingDefaultAdmin(client, {
  address: "0x1234567891234567891234567891234567891234",
});

pendingDefaultAdminDelay

Returns the pending delay and the timestamp at which it takes effect. A zero effectSchedule means that no delay change is pending. DefaultAdminRules only. View docs

pendingDefaultAdminDelay(client, { address });
  • client: Client — from viem — (required)
  • address: Address — AccessControl contract address (required)

Example:

import { pendingDefaultAdminDelay } from "viem-oz-access-control/actions";
const [newDelay, effectSchedule] = await pendingDefaultAdminDelay(client, {
  address: "0x1234567891234567891234567891234567891234",
});

renounceRole

Gives up a role. callerConfirmation must be the caller's own address, otherwise the contract reverts with AccessControlBadConfirmation. On a DefaultAdminRules contract, giving up DEFAULT_ADMIN_ROLE needs two steps: first call beginDefaultAdminTransfer with the zero address, then acceptDefaultAdminTransfer. View docs

renounceRole(client, { address, callerConfirmation, role });
  • client: Client — from viem — (required)
  • address: Address — AccessControl contract address (required)
  • callerConfirmation: Address — The caller's own address (required)
  • role: Hash — Role identifier, 32 bytes (required)

Example:

import { roleId } from "viem-oz-access-control";
import { renounceRole } from "viem-oz-access-control/actions";
const hash = await renounceRole(client, {
  address: "0x1234567891234567891234567891234567891234",
  callerConfirmation: client.account.address,
  role: roleId("KEEPER_ROLE"),
});

revokeRole

Takes a role away from an account. The caller must hold the admin role of that role. On a DefaultAdminRules contract this reverts for DEFAULT_ADMIN_ROLE. View docs

revokeRole(client, { account, address, role });
  • client: Client — from viem — (required)
  • account: Address — Address that loses the role (required)
  • address: Address — AccessControl contract address (required)
  • role: Hash — Role identifier, 32 bytes (required)

Example:

import { roleId } from "viem-oz-access-control";
import { revokeRole } from "viem-oz-access-control/actions";
const hash = await revokeRole(client, {
  account: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd",
  address: "0x1234567891234567891234567891234567891234",
  role: roleId("KEEPER_ROLE"),
});

rollbackDefaultAdminDelay

Cancels a scheduled delay change. Only the current default admin can call it. DefaultAdminRules only. View docs

rollbackDefaultAdminDelay(client, { address });
  • client: Client — from viem — (required)
  • address: Address — AccessControl contract address (required)

Example:

import { rollbackDefaultAdminDelay } from "viem-oz-access-control/actions";
const hash = await rollbackDefaultAdminDelay(client, {
  address: "0x1234567891234567891234567891234567891234",
});

Helpers

The package root exports the values needed to build role identifiers, plus the ABIs.

roleId

Returns the 32-byte identifier of a role name. It matches keccak256("ROLE_NAME") in Solidity.

import { roleId } from "viem-oz-access-control";
const keeperRole = roleId("KEEPER_ROLE");

defaultAdminRole

The identifier of the contract's DEFAULT_ADMIN_ROLE. It is 32 zero bytes for every AccessControl contract, so no contract call is needed.

import { defaultAdminRole } from "viem-oz-access-control";

ABIs

accessControlAbi holds the base functions, events, and errors of AccessControl. accessControlDefaultAdminRulesAbi holds the same entries plus the ones of AccessControlDefaultAdminRules. Use them to decode logs, or to decode a revert such as AccessControlUnauthorizedAccount.

import { accessControlAbi } from "viem-oz-access-control";

Usage with .extend()

You can extend your viem client with AccessControl actions using .extend() and the provided helpers:

import { createPublicClient, createWalletClient, http } from "viem";
import {
  accessControlPublicActions,
  accessControlWalletActions,
  roleId,
} from "viem-oz-access-control";

// Example: extending a public client
const publicClient = createPublicClient({
  chain, // your chain config
  transport: http(),
}).extend(accessControlPublicActions());

// Now you can call:
const isKeeper = await publicClient.hasRole({
  account: "0xYourWalletAddress",
  address: "0x1234567891234567891234567891234567891234",
  role: roleId("KEEPER_ROLE"),
});

// Example: extending a wallet client
const walletClient = createWalletClient({
  account, // your account config
  chain, // your chain config
  transport: http(),
}).extend(accessControlWalletActions());

// Now you can call:
const tx = await walletClient.grantRole({
  account: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd",
  address: "0x1234567891234567891234567891234567891234",
  role: roleId("KEEPER_ROLE"),
});

Notes

AccessControlDefaultAdminRules also exposes owner(), from ERC-5313. It returns the same value as defaultAdmin(). This package does not wrap it.

Local Setup

This repository uses pnpm as the package manager. Enable Corepack to use the pinned version automatically:

corepack enable

To install the dependencies, run:

pnpm install

To run the tests, run:

pnpm test

To run the tests with a coverage report, run:

pnpm test:coverage