Registering a Module

Learn the process of registering a Module with the Lens Protocol.

Developers can register a module with the ModuleRegistry contract to make it available to frontends, the Lens API, and users.

Registration is a declarative process that emits an event, signaling the availability of the new module. The data provided during registration isn't verified on-chain, so it should not be blindly trusted. Instead, it should serve as an indication of the available modules and their potential types.

The Lens Protocol uses the ERC-165 standard to determine if the module supports the required interfaces.

ModuleRegistry Standards

For a module to be registered, it must adhere to the ModuleRegistry Standards. Specifically, it must:

  • Conform to the ILensModule interface

  • Declare its conformance to the specific module type interface (such as IFollowModule, IPublicationActionModule, or IReferenceModule)

ILensModule Interface

First, the module should declare its conformance to the ILensModule interface by implementing the ERC-165 interface for the LENS_MODULE interfaceID.

function supportsInterface(bytes4 interfaceID) public pure virtual override returns (bool) {  return interfaceID == bytes4(keccak256(abi.encodePacked('LENS_MODULE')));}

The supportsInterface function is inherited from LensModule.sol.

Next, you need to implement the getModuleMetadataURI() getter according to the ILensModule interface. For more information, see the Module Metadata section.

function getModuleMetadataURI() external view returns (string memory) {  return 'yourMetadataURIgoesHere';}

Module Type Interface

The module should declare its conformance to the specific module type. This could be IFollowModule for Follow Modules, IPublicationActionModule for Open Action Modules, or IReferenceModule for Reference Modules. It does this by implementing the ERC-165 interface for the interfaceID specified in the respective module interface.

Here's an example of how am Open Action Module might implement this inheritance:

contract CollectPublicationAction is LensModule, IPublicationActionModule {  function supportsInterface(bytes4 interfaceID) public pure override returns (bool) {      return interfaceID == type(IPublicationActionModule).interfaceId || super.supportsInterface(interfaceID);  }
  // ...}

Upfront Registration

Typically there's no need to register a module in advance, as it will be automatically registered upon its first use (for example, when the first post that uses this module is created). However, if you want to announce the availability of your module upfront, you can manually do so.

To manually register a module, provide its address and the appropriate type to the registerModule() function of the ModuleRegistry contract:

registerModule(address moduleAddress, uint256 moduleType);

In this context, moduleType is an enum that represents the type of the module:

Module TypeValue
Open Action Module1
Reference Module2
Follow Module3

If you mistakenly pass the wrong module type during registration, the module will not be registered. This is because the ModuleRegistry verifies the ERC-165 standards of your module, and if these don't match the declared type, the process is reverted.

If you're registering a contract that implements multiple module interfaces, you should register it multiple times, each time using the correct module type.