Modular roles and permissions as non-transferable ERC-1155 tokens ("hats") arranged in a tree. Hats can gate Safe signers, Snapshot voting, Discord/Telegram access, and any onchain authority via plug-in eligibility/toggle modules.
- 01DAO role management
- 02permission delegation
- 03Safe signer gating
- 04Snapshot strategy gating
- 05modular authorities
- pnpm add @hatsprotocol/sdk-v1-core @hatsprotocol/sdk-v1-subgraph viem
| Variable | Scope | Description |
|---|---|---|
| HATS_CHAIN_ID | Client | Numeric chain id (e.g. 1, 10, 137, 8453). Hats v1 is deployed at the same address (0x3bc1A0Ad72417f2d411118085256fC53CBdDd137) on every supported chain. |
Use Hats Protocol for role-based permissioning. Instantiate `new HatsClient({ chainId, publicClient, walletClient })` from `@hatsprotocol/sdk-v1-core`. Create a top hat with `mintTopHat`, then build the tree with `createHat({ admin, details, maxSupply, eligibility, toggle, mutable, imageURI })`. Mint roles with `mintHat({ hatId, wearer })` and check authority with `isWearerOfHat(wearer, hatId)`. Hat IDs are 256-bit packed paths — query the tree via `@hatsprotocol/sdk-v1-subgraph` (`hatsSubgraphClient.getTree({ chainId, treeId })`) rather than scanning logs. Combine with the Hats Signer Gate to control Safe signers programmatically.
- ⚑Hat IDs are not sequential — they're 256-bit hierarchical paths (top hat = `0x000000010...`). Always use the SDK helpers (`hatIdToTreeId`, `treeIdToTopHatId`) instead of hand-packing them.
- ⚑Tree IDs are the top 32 bits of a top hat ID; passing a numeric tree ID where a full hat ID is expected (or vice versa) is the most common subgraph bug.
- ⚑Hats are non-transferable ERC-1155s — `safeTransferFrom` reverts. Reassignment goes through the eligibility module returning ineligible + a `mintHat` to the new wearer.
- ⚑Eligibility and toggle modules can revoke a hat at any block — never cache wearer status across requests; re-check before authorizing privileged actions.
- ⚑When using the Hats Signer Gate with Safe, the gate replaces the Safe's signer set — direct `addOwnerWithThreshold` calls outside the gate will be reverted by the module's guard.