Vesting 2.0 role constants.
The roles are unchanged from 1.6: the deployer holds DEFAULT_ADMIN_ROLE and every operational role (creator, revoker, withdrawer, claimer, disclosure admin, and pauser on pausable clones) on its manager clone and can delegate them. FEE_COLLECTOR_ROLE is held by the factory's fee collector. FEE_MANAGER_ROLE is a factory role and never appears on a clone. What changed is the hook surface: the grantee is now called holder.
| Role | Permits | Granted by |
|---|---|---|
| DEFAULT_ADMIN_ROLE 0x0000000000000000…000000 | Grant and revoke the other manager roles (except FEE_COLLECTOR_ROLE, which is self-administered), and call setMaxBatchSize / setMaxRevokeBatchSize. Held by the deployer. directVestingTransfer is not an admin call: only the vesting's current recipient can make it. | DEFAULT_ADMIN_ROLE |
| VESTING_CREATOR_ROLE 0xf775c0bcd58c044b…313ee7 | createVesting and batchCreateVesting. preflightCreateVesting reports a missing grant as an AccessDeniedError in blockerErrors. | DEFAULT_ADMIN_ROLE |
| REVOKER_ROLE 0xce3f34913921da55…deee30 | revokeVesting and batchRevokeVesting on revocable schedules that have not ended. | DEFAULT_ADMIN_ROLE |
| CLAIMER_ROLE 0x11a8cb5a02bd6c42…1d9c78 | adminClaim and adminPartialClaim - claim on a recipient's behalf; the tokens still go to the recipient. | DEFAULT_ADMIN_ROLE |
| WITHDRAWER_ROLE 0x10dac8c06a04bec0…1334e4 | withdrawAdmin (including the unvested remainder a revoke releases), withdrawOtherToken and withdrawOtherConfidentialToken. | DEFAULT_ADMIN_ROLE |
| FEE_COLLECTOR_ROLE 0x2dca0f5ce7e75a4b…038821 | withdrawGasFee and withdrawTokenFee (withdrawTokenFee only applies to DistributionToken clones). Held by the factory's fee collector (TokenOps), not the clone deployer. Self-administered: the current collector hands it off with transferFeeCollectorRole; DEFAULT_ADMIN_ROLE cannot grant or revoke it. | FEE_COLLECTOR_ROLE (transferFeeCollectorRole) |
| PAUSER_ROLE 0x65d7a28e3265b37a…0d862a | pause and unpause on pausable clones. While paused, recipient claims and partial claims, splits, and initiating, accepting or direct transfers revert. adminClaim / adminPartialClaim (CLAIMER_ROLE), cancelVestingTransfer, revokes, withdrawals, disclosures and createVesting are not pause-gated. | DEFAULT_ADMIN_ROLE |
| DISCLOSURE_ADMIN_ROLE 0xcf8a7913f3d76add…feb0c8 | adminDiscloseToParty, adminBatchDiscloseToParty and the adminGet* encrypted views, for compliance flows without recipient consent. | DEFAULT_ADMIN_ROLE |
Factory roles
These roles live on the ConfidentialVestingFactory, not on a manager clone, and are not part of useRoleConstants. Read them off the factory ABI (confidentialVestingFactoryAbi) via readContract until the SDK exports a factory role-constants helper.
| Role | Permits | Granted by |
|---|---|---|
| FEE_MANAGER_ROLE 0x6c0757dc3e6b28b2…04ff1c | The factory fee config: setDefaultGasFee, setDefaultTokenFee, setDefaultFeeType, setCustomFee, disableCustomFee, setFeeCollector, resetGasFee, resetTokenFee. | Factory DEFAULT_ADMIN_ROLE |
Reading + managing
Role hooks take holder
useHasRole takes holder, and useGrantRole / useRevokeRole take { role, holder } as mutation variables, matching /fhe-airdrop and /fhe-disperse. UseGrantRoleArgs and UseRevokeRoleArgs are unions that accept exactly one of holder or the deprecated accountTarget. The headless grantRole(role, accountTarget) is positional and unchanged.
import { useHasRole, useGrantRole, useRoleConstants } from "@tokenops/sdk/fhe-vesting/react";
const { data: roles } = useRoleConstants({ address: manager }); // immutable: staleTime Infinity
const { data: isCreator } = useHasRole({
address: manager,
role: roles?.VESTING_CREATOR_ROLE,
holder: teammate,
});
const grant = useGrantRole({ address: manager });
grant.mutate({ role: roles!.VESTING_CREATOR_ROLE, holder: teammate });
// accountTarget (write) cannot be combined with holder. On useHasRole,
// holder takes precedence over the deprecated account.