Hats Protocol Docs
hatsprotocol.xyzGithub
  • πŸ‘‹Welcome to Hats Protocol
  • 🧒Getting Started with Hats
  • ⭐Quick Start
  • Using The Hats App
    • 🀠Essentials For Hat Wearers
    • 🎩Creating My First Hat
    • πŸ§™Admins: Creating, Issuing, and Revising Hats
    • πŸ‘₯What Hats Do I Need?
    • 🌳Drafting, Exporting, and Deploying Tree Changes
    • πŸ—οΈSetting a Hat's Basic Properties
    • πŸ₯³Adding Wearers
    • πŸ”Connecting Hats w/ Permissions & Authorities
      • Types of Hat-Powered Authorities
      • Connecting Hats to Token Gates
        • Hats Protocol Contract Addresses
        • Finding a Hat's Token ID
      • Documenting Hat Powers & Responsibilities
    • 🌟Revocation & Eligibility: Requirements for Wearers
    • ⚑Deactivating & Reactivating Hats
    • βœ…Making Hats Claimable
    • πŸ”—Linking Trees Together
    • ⛓️Hats Protocol Supported Chains
    • ❓Glossary & FAQ
  • Hats Integrations
    • πŸ”Permissions & Authorities
      • Coordinape
      • Council Voting Vault
      • Charmverse
      • Discord
        • Collab.Land --> Discord
        • Guild.xyz --> Discord
      • Farcaster Casting Rights
      • Fileverse
      • Google Workspace
      • Hats Account
      • Role-Based Compensation
      • Safe Multisig Signing Authority
      • Telegram
        • Collab.Land --> Telegram
        • Guild.xyz --> Telegram
      • Snapshot: Voting, Weight & Proposal Creation
      • Wonderverse
    • 🌟Eligibility & Accountability Criteria
      • Agreement Eligibility
      • Allow-List Eligibility
      • CoLinks Eligibility
      • ERC20 Eligibility
      • ERC721 Eligibility
      • ERC1155 Eligibility
      • Hat-Wearing Eligibility
      • Hats Election Eligibility
      • JokeRace Eligibility
      • Pass-Through (Hat-Based) Eligibility
      • Staking Eligibility
      • Subscription or Membership Fee (Unlock Protocol)
      • Gitcoin Passport Eligibility
    • ⚑Activation & Deactivation Criteria
      • Seasonal/ Time-Expiry Toggle
      • Pass-Through (Hat-Based) Toggle
    • πŸ‘·Hatter Modules
      • Multi Claims Hatter
      • DAOhaus Moloch v3 Membership & Share Allocation
  • For Developers
    • πŸ‘·Hats Protocol, for Developers
      • Hat Properties
      • Wearing a Hat
      • Hat Admins & Hatter Contracts
      • Hats Trees
      • Hat IDs
      • Linking Hats Trees
      • Eligibility Modules
      • Toggle Modules
      • Hat Mutability and Editing
      • Creating Hats
      • Minting Hats
      • Transfering Hats
      • Renouncing Hats
      • Batch Actions
      • Hat Image URIs
      • ERC1155 Compatibility
      • ⛓️Supported Chains
    • πŸ€–v1 Protocol Spec
      • Hats.sol
      • HatsEvents.sol
      • HatsErrors.sol
      • HatsIdUtilities.sol
      • Interfaces
        • IHats.sol
        • IHatsIdUtilities.sol
        • IHatsEligibility.sol
        • IHatsToggle.sol
    • πŸ–₯️v1 SDK
      • Core
        • Getting Started
        • Onchain Reads
        • Onchain Writes
        • Multicall
        • Claiming Hats
        • Utilities
      • Subgraph
        • Getting Started
        • Fetching Hats
        • Fetching Wearers
        • Fetching Trees
        • Misc
        • Types
      • Hat Details
        • Getting Started
        • Usage
    • πŸ”­v1 Subgraphs
    • 🧩Hats Modules
      • πŸ”ŒModules SDK
        • Getting Started
        • Get Available Modules
        • Create New Instance/s
        • Composing Modules
        • Interact With Instances
        • Utilities
        • Types
      • βš’οΈBuilding Hats Modules
        • Inside a Hats Module
          • Immutable Arguments
          • Module Setup
          • Versioning
        • Creating New Modules
        • How Module Instances Are Deployed
        • Modules Registry
        • About Module Chains
    • πŸ”Hats Signer Gate v2
    • πŸ‘’Hats Signer Gate SDK
      • Getting Started
      • Creating New Instances
      • Hats Signer Gate
      • Multi Hats Signer Gate
      • HSG & MHSG Handlers
    • πŸ’ΌHats Account SDK
      • 1 of N Hats Account
        • Getting Started
        • Creating New Instances
        • Executing From An Instance
        • Constants
        • Types
    • 🌐Hats Security Audits
  • Legal
    • Terms
      • Terms of Service
      • Acceptable Use
      • Privacy Policy
      • Cookie Policy
      • Attribution
Powered by GitBook
On this page
  • Getting Started
  • Best Practices
  • Learn From Examples
  1. For Developers
  2. Hats Modules
  3. Building Hats Modules

Creating New Modules

PreviousVersioningNextHow Module Instances Are Deployed

Last updated 8 months ago

Getting Started

The repository makes it easy to get started building a new module. It has everything you need, including:

  • An initialized Foundry project with a Hats-relevant config.

  • Initial dependencies added: forge-std and hats-module.

  • A stubbed out starter module contract.

  • Test & deployment files boilerplate.

  • Github CI workflows for Forge tests and gas cost diffs.

For eligibility modules, import and inherit from the contract, which inherits from HatsModule and additionally implements the interface:

import { HatsEligibilityModule } from "hats-module/HatsModule.sol";

Similarly, for toggle modules, import and inherit from the contract, which inherits from HatsModule and additionally implements the interface:

import { HatsToggleModule } from "hats-module/HatsModule.sol";

Best Practices

For compatibility with , it is strongly recommended to adhere to the following practices:

Pull, don't push

Avoid pushing hat or hat wearer status directly to the protocol, i.e. via IHats.setHatStatus or IHats.setHatWearerStatus. These functions are only authorized to contracts set directly on the given hat as the toggle or eligibility module, respectively. Those calls would therefore revert when called from a module in a chain.

The simplest alternative is to not force the protocol to recognize any status updates, just let it pull them in dynamically the next time they are checked.

If you must have the protocol immediately recognize a new status, have the protocol pull the updates, ie via IHats.checkHatStatus or IHats.checkHatWearerStatus. These are fully public functions that will trigger the protocol to pull the current status from the modules set on the hat; if that's a chain, it will read from all the modules in the chain.

Don't force claiming

When building such a module, avoid requiring that would-be-wearers claim the hat at the same time as taking the action to become eligible. Instead, give them an option to take the qualifying action independently, as well as bundled with claiming. This will allow your module to work properly even when chained with another module that uses the qualifying action + claim approach.

This is necessary because of the way the protocol handles minting when an eligibility module is attached to the hat. With a module attached, the protocol will only allow the hat to be minted if the recipient wearer is "explicitly eligible," i.e. eligible according to the module. In the case of a module chain, this will include eligibility information from all the modules in the chain, and so the would-be wearer may not be eligible for the hat as a whole even after they execute the qualifying action for one of its chained modules.

Learn From Examples

To learn more and get inspiration, check out the awesome module that are already here:

Some eligibility modules (such as Agreement Eligibility and Staking Eligibility)Β include an option for would-be-wearers to at the same time as they take an action to become eligible (e.g., signing the agreement and staking, respectively).

🧩
βš’οΈ
hats-module-template
HatsEligibilityModule
IHatsEligibility
HatsToggleModule
IHatsToggle
module chains
claim the hat
Eligibility Modules
Hatter Modules
Toggle Modules