Step 2: Register Operator
Before any vault can be onboarded, the address that will call registerVault() must hold OPERATOR_ROLE on the target VaultRegistrar. The operator is your protocol contract or vault factory — the address that is msg.sender when registerVault() runs.
How to obtain OPERATOR_ROLE
On this testnet sandbox (permissionless)
addOperator() on this deployment is permissionless — no admin key required.
Go to the Register as Operator page, enter your protocol contract address, and submit. The transaction is sent directly from your wallet.
You can verify the role was granted immediately — the page shows "Already registered" once confirmed.
Production or admin-gated deployments
addOperator(address) is gated by DEFAULT_ADMIN_ROLE. Only the registrar admin can grant the role.
If you control the admin key:
# from bc-vault-registrar
npx hardhat add-operator \
--registrar <VAULT_REGISTRAR_PROXY_ADDRESS> \
--operator <YOUR_FACTORY_OR_PROTOCOL_ADDRESS> \
--network <NETWORK>
The task is idempotent: if the address already has the role, it exits without sending a transaction.
If you do not control the admin key:
Contact the registrar admin with your proxy address, your factory address, and the target chain. The RoleGranted event (OZ AccessControl) will be emitted on-chain for OPERATOR_ROLE.
After confirmation, verify:
const isOp = await publicClient.readContract({
address: registrar,
abi: vaultRegistrarAbi,
functionName: "isOperator",
args: [yourFactoryAddress],
});
Common mistakes
- Granting the role to an EOA when your factory is a contract. The role must be on the address that is
msg.senderforregisterVault(). - Granting on the wrong chain. Roles are per-deployment. Grant on every chain where you intend to register vaults.
Operator checklist
- Your factory/protocol contract has
OPERATOR_ROLEon every target chain. -
isOperator(yourFactoryAddress) == truefrom any RPC.