IPcl.registerPolicyTemplate / removePolicyTemplate

registerPolicyTemplate(
  string calldata templateId
) external
removePolicyTemplate(string calldata templateId) external

Chain-wide policy admin operations that add or remove one of the built-in PCL policy templates from the active registry. registerPolicyTemplate makes a template ID available for instantiation inside a PolicySet; removePolicyTemplate withdraws it. Only the address returned by IPcl.policyAdmin() may call these — other callers revert with Unauthorized(). Both calls, when made by the admin against the PCL precompile, bypass PCL policy evaluation via the admin recovery path, so they cannot be blocked by a misconfigured global policy that would otherwise reject the admin's own address.

Parameters

Name Type Required Description
templateId string ✓ The template identifier — one of the built-in IDs shipped with the chain: EAS_POLICY, DENYLIST_POLICY, VOLUME_POLICY, PERIODIC_VOLUME_POLICY, AGENT_OKRW_TRANSFER_LIMIT_POLICY, LOGICAL_POLICY, FOR_EACH_POLICY. Registering any other ID reverts with InvalidPolicyTemplate(input) (on maroo-testnet-1 the registry still holds the removed OKRW_EAS_TRANSFER_LIMIT_POLICY and OKRW_EAS_PERIODIC_VOLUME_LIMIT_POLICY, so registering either reverts with DuplicatedPolicyTemplate instead, and a PolicySet naming either is rejected with UnknownPolicyType); registering an already-registered ID reverts with DuplicatedPolicyTemplate(templateId); removing an ID that is not registered does not revert.

Returns

Type: void

No return value. Success emits PolicyTemplateRegistered(templateId) or PolicyTemplateRemoved(templateId).

Errors

Code Name Description
Unauthorized Unauthorized Reverts when the caller is not the address returned by IPcl.policyAdmin().
InvalidPolicyTemplate InvalidPolicyTemplate Reverts when templateId does not match any built-in template shipped with the chain. Encoded as InvalidPolicyTemplate(string input).
DuplicatedPolicyTemplate DuplicatedPolicyTemplate Reverts on registerPolicyTemplate when the template is already in the active registry. Encoded as DuplicatedPolicyTemplate(string templateId).

Examples

Register a template as the policy admin

The call must originate from the current policyAdmin() address. Because the admin is calling one of the four PCL control-plane selectors on the PCL precompile, the transaction bypasses PCL policy evaluation and cannot be blocked by a global policy that would otherwise reject the admin's address.

import { createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";

const PCL = "0x1000000000000000000000000000000000000005" as const;
const pclAbi = [
  { type: "function", name: "registerPolicyTemplate", stateMutability: "nonpayable",
    inputs: [{ name: "templateId", type: "string" }], outputs: [] },
  { type: "function", name: "removePolicyTemplate", stateMutability: "nonpayable",
    inputs: [{ name: "templateId", type: "string" }], outputs: [] },
] as const;

const admin = createWalletClient({
  account: privateKeyToAccount(process.env.POLICY_ADMIN_KEY as `0x${string}`),
  transport: http("https://rpc-testnet.maroo.io"),
});

await admin.writeContract({
  address: PCL,
  abi: pclAbi,
  functionName: "registerPolicyTemplate",
  args: ["EAS_POLICY"],
});

Removing a template no longer checks for consumers

Removing a template is now a pure registry operation: it does not scan for contracts or global policies that reference the template. Any PolicySet left pointing at a removed template will fail at evaluation time with PolicyNotRegistered against the caller whose transaction triggered the check, not against the admin who performed the removal.

// Previously this could revert with `PolicyTemplateInUse` when a contract
// policy or the global config still referenced the template. That check has
// been removed; the call succeeds whenever the caller is the policy admin
// (even for an ID that is not registered).
await admin.writeContract({
  address: PCL,
  abi: pclAbi,
  functionName: "removePolicyTemplate",
  args: ["VOLUME_POLICY"],
});

// Outstanding `PolicySet` entries that still reference "VOLUME_POLICY" will
// now cause the *user transaction* they gate to revert with
// `PolicyNotRegistered("VOLUME_POLICY")` when PCL evaluates it. The admin
// is expected to clean up (or re-register) the template before it removes it.
ESC
Type to search