Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(licensing): enable multi-license attachment and licensing config during IP registration #134

Merged
merged 2 commits into from
Nov 30, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 11 additions & 19 deletions contracts/interfaces/workflows/IGroupingWorkflows.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ interface IGroupingWorkflows {
/// @param spgNftContract The address of the SPGNFT collection.
/// @param groupId The ID of the group IP to add the newly registered IP.
/// @param recipient The address of the recipient of the minted NFT.
/// @param licenseTemplate The address of the license template to be attached to the new IP.
/// @param licenseTermsId The ID of the registered license terms that will be attached to the new IP.
/// @param licensesData The data of the licenses and their configurations to be attached to the new IP.
/// @param ipMetadata OPTIONAL. The desired metadata for the newly minted NFT and registered IP.
/// @param sigAddToGroup Signature data for addIp to the group IP via the Grouping Module.
/// @param allowDuplicates Set to true to allow minting an NFT with a duplicate metadata hash.
Expand All @@ -23,8 +22,7 @@ interface IGroupingWorkflows {
address spgNftContract,
address groupId,
address recipient,
address licenseTemplate,
uint256 licenseTermsId,
WorkflowStructs.LicenseData[] calldata licensesData,
WorkflowStructs.IPMetadata calldata ipMetadata,
WorkflowStructs.SignatureData calldata sigAddToGroup,
bool allowDuplicates
Expand All @@ -35,48 +33,42 @@ interface IGroupingWorkflows {
/// @param nftContract The address of the NFT collection.
/// @param tokenId The ID of the NFT.
/// @param groupId The ID of the group IP to add the newly registered IP.
/// @param licenseTemplate The address of the license template to be attached to the new IP.
/// @param licenseTermsId The ID of the registered license terms that will be attached to the new IP.
/// @param licensesData The data of the licenses and their configurations to be attached to the new IP.
/// @param ipMetadata OPTIONAL. The desired metadata for the newly registered IP.
/// @param sigMetadataAndAttach Signature data for setAll (metadata) and attachLicenseTerms to the IP
/// via the Core Metadata Module and Licensing Module.
/// @param sigMetadataAndAttachAndConfig Signature data for setAll (metadata), attachLicenseTerms, and
/// setLicensingConfig to the IP via the Core Metadata Module and Licensing Module.
/// @param sigAddToGroup Signature data for addIp to the group IP via the Grouping Module.
/// @return ipId The ID of the newly registered IP.
function registerIpAndAttachLicenseAndAddToGroup(
address nftContract,
uint256 tokenId,
address groupId,
address licenseTemplate,
uint256 licenseTermsId,
WorkflowStructs.LicenseData[] calldata licensesData,
WorkflowStructs.IPMetadata calldata ipMetadata,
WorkflowStructs.SignatureData calldata sigMetadataAndAttach,
WorkflowStructs.SignatureData calldata sigMetadataAndAttachAndConfig,
WorkflowStructs.SignatureData calldata sigAddToGroup
) external returns (address ipId);

/// @notice Register a group IP with a group reward pool and attach license terms to the group IP
/// @param groupPool The address of the group reward pool.
/// @param licenseTemplate The address of the license template to be attached to the new group IP.
/// @param licenseTermsId The ID of the registered license terms that will be attached to the new group IP.
/// @param licenseData The data of the license and its configuration to be attached to the new group IP.
/// @return groupId The ID of the newly registered group IP.
function registerGroupAndAttachLicense(
address groupPool,
address licenseTemplate,
uint256 licenseTermsId
WorkflowStructs.LicenseData calldata licenseData
) external returns (address groupId);

/// @notice Register a group IP with a group reward pool, attach license terms to the group IP,
/// and add individual IPs to the group IP.
/// @dev ipIds must be have the same license terms as the group IP.
/// @param groupPool The address of the group reward pool.
/// @param ipIds The IDs of the IPs to add to the newly registered group IP.
/// @param licenseTemplate The address of the license template to be attached to the new group IP.
/// @param licenseTermsId The ID of the registered license terms that will be attached to the new group IP.
/// @param licenseData The data of the license and its configuration to be attached to the new group IP.
/// @return groupId The ID of the newly registered group IP.
function registerGroupAndAttachLicenseAndAddIps(
address groupPool,
address[] calldata ipIds,
address licenseTemplate,
uint256 licenseTermsId
WorkflowStructs.LicenseData calldata licenseData
) external returns (address groupId);

/// @notice Collect royalties for the entire group and distribute the rewards to each member IP's royalty vault
Expand Down
38 changes: 17 additions & 21 deletions contracts/interfaces/workflows/ILicenseAttachmentWorkflows.sol
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;

import { PILTerms } from "@storyprotocol/core/interfaces/modules/licensing/IPILicenseTemplate.sol";

import { WorkflowStructs } from "../../lib/WorkflowStructs.sol";

/// @title License Attachment Workflows Interface
/// @notice Interface for IP license attachment workflows.
interface ILicenseAttachmentWorkflows {
/// @notice Register Programmable IP License Terms (if unregistered) and attach it to IP.
/// @param ipId The ID of the IP.
/// @param terms The PIL terms to be registered.
/// @param sigAttach Signature data for attachLicenseTerms to the IP via the Licensing Module.
/// @return licenseTermsId The ID of the newly registered PIL terms.
/// @param pilTermsData The PIL terms and licensing configuration data to be attached to the IP.
/// @param sigAttachAndConfig Signature data for attachLicenseTerms and setLicensingConfig to the IP via the Licensing Module.
/// @return licenseTermsIds The IDs of the newly registered PIL terms.
function registerPILTermsAndAttach(
address ipId,
PILTerms calldata terms,
WorkflowStructs.SignatureData calldata sigAttach
) external returns (uint256 licenseTermsId);
WorkflowStructs.PILTermsData[] calldata pilTermsData,
WorkflowStructs.SignatureData calldata sigAttachAndConfig
) external returns (uint256[] memory licenseTermsIds);

/// @notice Mint an NFT from a SPGNFT collection, register it with metadata as an IP,
/// register Programmable IPLicense
Expand All @@ -26,36 +23,35 @@ interface ILicenseAttachmentWorkflows {
/// @param spgNftContract The address of the SPGNFT collection.
/// @param recipient The address of the recipient of the minted NFT.
/// @param ipMetadata OPTIONAL. The desired metadata for the newly minted NFT and registered IP.
/// @param terms The PIL terms to be registered.
/// @param pilTermsData The PIL terms and licensing configuration data to be attached to the IP.
/// @param allowDuplicates Set to true to allow minting an NFT with a duplicate metadata hash.
/// @return ipId The ID of the newly registered IP.
/// @return tokenId The ID of the newly minted NFT.
/// @return licenseTermsId The ID of the newly registered PIL terms.
/// @return licenseTermsIds The IDs of the newly registered PIL terms.
function mintAndRegisterIpAndAttachPILTerms(
address spgNftContract,
address recipient,
WorkflowStructs.IPMetadata calldata ipMetadata,
PILTerms calldata terms,
WorkflowStructs.PILTermsData[] calldata pilTermsData,
bool allowDuplicates
) external returns (address ipId, uint256 tokenId, uint256 licenseTermsId);
) external returns (address ipId, uint256 tokenId, uint256[] memory licenseTermsIds);

/// @notice Register a given NFT as an IP and attach Programmable IP License Terms.
/// @dev Because IP Account is created in this function, we need to set the permission via signature to allow this
/// contract to attach PIL Terms to the newly created IP Account in the same function.
/// @param nftContract The address of the NFT collection.
/// @param tokenId The ID of the NFT.
/// @param ipMetadata OPTIONAL. The desired metadata for the newly registered IP.
/// @param terms The PIL terms to be registered.
/// @param sigMetadata OPTIONAL. Signature data for setAll (metadata) for the IP via the Core Metadata Module.
/// @param sigAttach Signature data for attachLicenseTerms to the IP via the Licensing Module.
/// @param pilTermsData The PIL terms and licensing configuration data to be attached to the IP.
/// @param sigMetadataAndAttachAndConfig Signature data for setAll (metadata), attachLicenseTerms, and
/// setLicensingConfig to the IP via the Core Metadata Module and Licensing Module.
/// @return ipId The ID of the newly registered IP.
/// @return licenseTermsId The ID of the newly registered PIL terms.
/// @return licenseTermsIds The IDs of the newly registered PIL terms.
function registerIpAndAttachPILTerms(
address nftContract,
uint256 tokenId,
WorkflowStructs.IPMetadata calldata ipMetadata,
PILTerms calldata terms,
WorkflowStructs.SignatureData calldata sigMetadata,
WorkflowStructs.SignatureData calldata sigAttach
) external returns (address ipId, uint256 licenseTermsId);
WorkflowStructs.PILTermsData[] calldata pilTermsData,
WorkflowStructs.SignatureData calldata sigMetadataAndAttachAndConfig
) external returns (address ipId, uint256[] memory licenseTermsIds);
}
44 changes: 28 additions & 16 deletions contracts/lib/LicensingHelper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,57 @@ pragma solidity 0.8.26;

import { Errors as CoreErrors } from "@storyprotocol/core/lib/Errors.sol";
import { ILicensingModule } from "@storyprotocol/core/interfaces/modules/licensing/ILicensingModule.sol";
import { IPILicenseTemplate, PILTerms } from "@storyprotocol/core/interfaces/modules/licensing/IPILicenseTemplate.sol";
import { IPILicenseTemplate } from "@storyprotocol/core/interfaces/modules/licensing/IPILicenseTemplate.sol";
import { Licensing } from "@storyprotocol/core/lib/Licensing.sol";

import { WorkflowStructs } from "./WorkflowStructs.sol";

/// @title Periphery Licensing Helper Library
/// @notice Library for all licensing related helper functions for Periphery contracts.
library LicensingHelper {
/// @dev Registers PIL License Terms and attaches them to the given IP.
/// @dev Registers PIL License Terms and attaches them to the given IP and sets their licensing configurations.
/// @param ipId The ID of the IP.
/// @param pilTemplate The address of the PIL License Template.
/// @param licensingModule The address of the Licensing Module.
/// @param licenseRegistry The address of the License Registry.
/// @param terms The PIL terms to be registered.
/// @param pilTermsData The PIL terms and licensing configuration data to be attached to the IP.
/// @return licenseTermsId The ID of the registered PIL terms.
function registerPILTermsAndAttach(
function registerPILTermsAndAttachAndSetConfigs(
address ipId,
address pilTemplate,
address licensingModule,
address licenseRegistry,
PILTerms calldata terms
WorkflowStructs.PILTermsData memory pilTermsData
) internal returns (uint256 licenseTermsId) {
licenseTermsId = IPILicenseTemplate(pilTemplate).registerLicenseTerms(terms);

attachLicenseTerms(ipId, licensingModule, licenseRegistry, pilTemplate, licenseTermsId);
licenseTermsId = IPILicenseTemplate(pilTemplate).registerLicenseTerms(pilTermsData.terms);
attachLicenseTermsAndSetConfigs(
ipId,
licensingModule,
pilTemplate,
licenseTermsId,
pilTermsData.licensingConfig
);
}

/// @dev Attaches license terms to the given IP.
/// @dev Attaches license terms to the given IP and sets their licensing configurations.
/// @param ipId The ID of the IP.
/// @param licensingModule The address of the Licensing Module.
/// @param licenseRegistry The address of the License Registry.
/// @param licenseTemplate The address of the license template.
/// @param licenseTermsId The ID of the license terms to be attached.
function attachLicenseTerms(
/// @param licensingConfig The licensing configuration for the license terms.
function attachLicenseTermsAndSetConfigs(
address ipId,
address licensingModule,
address licenseRegistry,
address licenseTemplate,
uint256 licenseTermsId
uint256 licenseTermsId,
Licensing.LicensingConfig memory licensingConfig
) internal {
try ILicensingModule(licensingModule).attachLicenseTerms(ipId, licenseTemplate, licenseTermsId) {
return; // license terms are attached successfully
// license terms are attached successfully, now we set the licensing config
ILicensingModule(licensingModule).setLicensingConfig(
ipId,
licenseTemplate,
licenseTermsId,
licensingConfig
);
} catch (bytes memory reason) {
// if the error is not that the license terms are already attached, revert with the original error
if (CoreErrors.LicenseRegistry__LicenseTermsAlreadyAttached.selector != bytes4(reason)) {
Expand Down
21 changes: 21 additions & 0 deletions contracts/lib/WorkflowStructs.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;

import { Licensing } from "@storyprotocol/core/lib/Licensing.sol";
import { PILTerms } from "@storyprotocol/core/interfaces/modules/licensing/IPILicenseTemplate.sol";

/// @title Workflow Structs Library
/// @notice Library for all the structs used in periphery workflows.
library WorkflowStructs {
Expand Down Expand Up @@ -42,4 +45,22 @@ library WorkflowStructs {
uint256 maxMintingFee;
uint32 maxRts;
}

/// @notice Struct for license data for license attachment on IP registration.
/// @param licenseTemplate The address of the license template to be used for the licensing.
/// @param licenseTermsId The ID of the license terms to be used for the licensing.
/// @param licensingConfig The licensing configuration for the IP.
struct LicenseData {
address licenseTemplate;
uint256 licenseTermsId;
Licensing.LicensingConfig licensingConfig;
}

/// @notice Struct for PIL terms data for PIL registration and attachment on IP registration.
/// @param terms The PIL terms to be used for the licensing.
/// @param licenseTermsConfig The licensing configuration for the PIL terms.
struct PILTermsData {
PILTerms terms;
Licensing.LicensingConfig licensingConfig;
}
}
Loading