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 in LicenseAttachmentWorkflows #125

Merged
merged 3 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions .github/workflows/foundry_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
pull_request:
branches:
- main
- release-v1.2.4

jobs:

Expand Down
18 changes: 9 additions & 9 deletions contracts/interfaces/workflows/ILicenseAttachmentWorkflows.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ interface ILicenseAttachmentWorkflows {
/// @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.
/// @return licenseTermsIds The IDs of the newly registered PIL terms.
function registerPILTermsAndAttach(
address ipId,
PILTerms calldata terms,
PILTerms[] calldata terms,
WorkflowStructs.SignatureData calldata sigAttach
) external returns (uint256 licenseTermsId);
) 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 @@ -29,13 +29,13 @@ interface ILicenseAttachmentWorkflows {
/// @param terms The PIL terms to be registered.
/// @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
) external returns (address ipId, uint256 tokenId, uint256 licenseTermsId);
PILTerms[] calldata terms
) 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
Expand All @@ -47,13 +47,13 @@ interface ILicenseAttachmentWorkflows {
/// @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.
/// @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,
PILTerms[] calldata terms,
WorkflowStructs.SignatureData calldata sigMetadata,
WorkflowStructs.SignatureData calldata sigAttach
) external returns (address ipId, uint256 licenseTermsId);
) external returns (address ipId, uint256[] memory licenseTermsIds);
}
14 changes: 8 additions & 6 deletions contracts/lib/LicensingHelper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,19 @@ library LicensingHelper {
/// @param licensingModule The address of the Licensing Module.
/// @param licenseRegistry The address of the License Registry.
/// @param terms The PIL terms to be registered.
/// @return licenseTermsId The ID of the registered PIL terms.
/// @return licenseTermsIds The IDs of the registered PIL terms.
function registerPILTermsAndAttach(
address ipId,
address pilTemplate,
address licensingModule,
address licenseRegistry,
PILTerms calldata terms
) internal returns (uint256 licenseTermsId) {
licenseTermsId = IPILicenseTemplate(pilTemplate).registerLicenseTerms(terms);

attachLicenseTerms(ipId, licensingModule, licenseRegistry, pilTemplate, licenseTermsId);
PILTerms[] calldata terms
) internal returns (uint256[] memory licenseTermsIds) {
licenseTermsIds = new uint256[](terms.length);
for (uint256 i = 0; i < terms.length; i++) {
licenseTermsIds[i] = IPILicenseTemplate(pilTemplate).registerLicenseTerms(terms[i]);
attachLicenseTerms(ipId, licensingModule, licenseRegistry, pilTemplate, licenseTermsIds[i]);
}
}

/// @dev Attaches license terms to the given IP.
Expand Down
28 changes: 16 additions & 12 deletions contracts/workflows/LicenseAttachmentWorkflows.sol
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,12 @@ contract LicenseAttachmentWorkflows is
/// @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.
/// @return licenseTermsIds The IDs of the newly registered PIL terms.
function registerPILTermsAndAttach(
address ipId,
PILTerms calldata terms,
PILTerms[] calldata terms,
WorkflowStructs.SignatureData calldata sigAttach
) external returns (uint256 licenseTermsId) {
) external returns (uint256[] memory licenseTermsIds) {
PermissionHelper.setPermissionForModule(
ipId,
address(LICENSING_MODULE),
Expand All @@ -107,7 +107,7 @@ contract LicenseAttachmentWorkflows is
sigAttach
);

licenseTermsId = LicensingHelper.registerPILTermsAndAttach(
licenseTermsIds = LicensingHelper.registerPILTermsAndAttach(
ipId,
address(PIL_TEMPLATE),
address(LICENSING_MODULE),
Expand All @@ -125,13 +125,17 @@ contract LicenseAttachmentWorkflows is
/// @param terms The PIL terms to be registered.
/// @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
) external onlyMintAuthorized(spgNftContract) returns (address ipId, uint256 tokenId, uint256 licenseTermsId) {
PILTerms[] calldata terms
)
external
onlyMintAuthorized(spgNftContract)
returns (address ipId, uint256 tokenId, uint256[] memory licenseTermsIds)
{
tokenId = ISPGNFT(spgNftContract).mintByPeriphery({
to: address(this),
payer: msg.sender,
Expand All @@ -140,7 +144,7 @@ contract LicenseAttachmentWorkflows is
ipId = IP_ASSET_REGISTRY.register(block.chainid, spgNftContract, tokenId);
MetadataHelper.setMetadata(ipId, address(CORE_METADATA_MODULE), ipMetadata);

licenseTermsId = LicensingHelper.registerPILTermsAndAttach(
licenseTermsIds = LicensingHelper.registerPILTermsAndAttach(
ipId,
address(PIL_TEMPLATE),
address(LICENSING_MODULE),
Expand All @@ -161,15 +165,15 @@ contract LicenseAttachmentWorkflows is
/// @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.
/// @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,
PILTerms[] calldata terms,
WorkflowStructs.SignatureData calldata sigMetadata,
WorkflowStructs.SignatureData calldata sigAttach
) external returns (address ipId, uint256 licenseTermsId) {
) external returns (address ipId, uint256[] memory licenseTermsIds) {
ipId = IP_ASSET_REGISTRY.register(block.chainid, nftContract, tokenId);
MetadataHelper.setMetadataWithSig(
ipId,
Expand All @@ -187,7 +191,7 @@ contract LicenseAttachmentWorkflows is
sigAttach
);

licenseTermsId = LicensingHelper.registerPILTermsAndAttach(
licenseTermsIds = LicensingHelper.registerPILTermsAndAttach(
ipId,
address(PIL_TEMPLATE),
address(LICENSING_MODULE),
Expand Down
18 changes: 11 additions & 7 deletions test/integration/workflows/DerivativeIntegration.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { ICoreMetadataModule } from "@storyprotocol/core/interfaces/modules/meta
import { IIPAccount } from "@storyprotocol/core/interfaces/IIPAccount.sol";
import { ILicensingModule } from "@storyprotocol/core/interfaces/modules/licensing/ILicensingModule.sol";
import { PILFlavors } from "@storyprotocol/core/lib/PILFlavors.sol";
import { IPILicenseTemplate, PILTerms } from "@storyprotocol/core/interfaces/modules/licensing/IPILicenseTemplate.sol";

// contracts
import { ISPGNFT } from "../../../contracts/interfaces/ISPGNFT.sol";
Expand Down Expand Up @@ -353,25 +354,28 @@ contract DerivativeIntegration is BaseIntegration {
)
);

PILTerms[] memory commTerms = new PILTerms[](1);
commTerms[0] = PILFlavors.commercialUse({
mintingFee: testMintFee,
currencyToken: testMintFeeToken,
royaltyPolicy: royaltyPolicyLRPAddr
});

StoryUSD.mint(testSender, testMintFee);
StoryUSD.approve(address(spgNftContract), testMintFee);
(address parentIpId, , uint256 licenseTermsIdParent) = licenseAttachmentWorkflows
(address parentIpId, , uint256[] memory licenseTermsIdParent) = licenseAttachmentWorkflows
.mintAndRegisterIpAndAttachPILTerms({
spgNftContract: address(spgNftContract),
recipient: testSender,
ipMetadata: testIpMetadata,
terms: PILFlavors.commercialUse({
mintingFee: testMintFee,
currencyToken: testMintFeeToken,
royaltyPolicy: royaltyPolicyLRPAddr
})
terms: commTerms
});

parentIpIds = new address[](1);
parentIpIds[0] = parentIpId;

parentLicenseTermIds = new uint256[](1);
parentLicenseTermIds[0] = licenseTermsIdParent;
parentLicenseTermIds[0] = licenseTermsIdParent[0];
parentLicenseTemplate = pilTemplateAddr;
}

Expand Down
Loading