@@ -8,11 +8,13 @@ import { ERC721Holder } from "@openzeppelin/contracts/token/ERC721/utils/ERC721H
8
8
import { ERC721URIStorageUpgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol " ;
9
9
import { IERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol " ;
10
10
import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol " ;
11
+ import { ICoreMetadataModule } from "@storyprotocol/core/interfaces/modules/metadata/ICoreMetadataModule.sol " ;
11
12
import { IIPAssetRegistry } from "@storyprotocol/core/interfaces/registries/IIPAssetRegistry.sol " ;
12
13
// solhint-disable-next-line max-line-length
13
14
import { ILicensingModule } from "@story-protocol/protocol-core/contracts/interfaces/modules/licensing/ILicensingModule.sol " ;
14
15
15
16
import { IOrgNFT } from "../interfaces/story-nft/IOrgNFT.sol " ;
17
+ import { WorkflowStructs } from "../lib/WorkflowStructs.sol " ;
16
18
17
19
/// @title Organization NFT
18
20
/// @notice Each organization token represents a Story ecosystem project.
@@ -22,18 +24,27 @@ contract OrgNFT is IOrgNFT, ERC721URIStorageUpgradeable, AccessManagedUpgradeabl
22
24
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
23
25
24
26
/// @notice Story Proof-of-Creativity IP Asset Registry address.
27
+ /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
25
28
IIPAssetRegistry public immutable IP_ASSET_REGISTRY;
26
29
27
30
/// @notice Story Proof-of-Creativity Licensing Module address.
31
+ /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
28
32
ILicensingModule public immutable LICENSING_MODULE;
29
33
34
+ /// @notice Core Metadata Module address.
35
+ /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
36
+ ICoreMetadataModule public immutable CORE_METADATA_MODULE;
37
+
30
38
/// @notice License template address.
39
+ /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
31
40
address public immutable LICENSE_TEMPLATE;
32
41
33
42
/// @notice License terms ID.
43
+ /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
34
44
uint256 public immutable LICENSE_TERMS_ID;
35
45
36
46
/// @notice Story NFT Factory address.
47
+ /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
37
48
address public immutable ORG_STORY_NFT_FACTORY;
38
49
39
50
/// @dev Storage structure for the OrgNFT
@@ -59,13 +70,15 @@ contract OrgNFT is IOrgNFT, ERC721URIStorageUpgradeable, AccessManagedUpgradeabl
59
70
constructor (
60
71
address ipAssetRegistry ,
61
72
address licensingModule ,
73
+ address coreMetadataModule ,
62
74
address orgStoryNftFactory ,
63
75
address licenseTemplate ,
64
76
uint256 licenseTermsId
65
77
) {
66
78
if (
67
79
ipAssetRegistry == address (0 ) ||
68
80
licensingModule == address (0 ) ||
81
+ coreMetadataModule == address (0 ) ||
69
82
orgStoryNftFactory == address (0 ) ||
70
83
licenseTemplate == address (0 )
71
84
) revert OrgNFT__ZeroAddressParam ();
@@ -75,6 +88,7 @@ contract OrgNFT is IOrgNFT, ERC721URIStorageUpgradeable, AccessManagedUpgradeabl
75
88
ORG_STORY_NFT_FACTORY = orgStoryNftFactory;
76
89
LICENSE_TEMPLATE = licenseTemplate;
77
90
LICENSE_TERMS_ID = licenseTermsId;
91
+ CORE_METADATA_MODULE = ICoreMetadataModule (coreMetadataModule);
78
92
79
93
_disableInitializers ();
80
94
}
@@ -93,36 +107,38 @@ contract OrgNFT is IOrgNFT, ERC721URIStorageUpgradeable, AccessManagedUpgradeabl
93
107
/// @notice Mints the root organization token and register it as an IP.
94
108
/// @dev This function is only callable by the OrgStoryNFTFactory contract.
95
109
/// @param recipient The address of the recipient of the root organization token.
96
- /// @param tokenURI_ The URI of the root organization token .
110
+ /// @param orgIpMetadata OPTIONAL. The desired metadata for the newly minted OrgNFT and registered IP .
97
111
/// @return rootOrgTokenId The ID of the root organization token.
98
112
/// @return rootOrgIpId The ID of the root organization IP.
99
113
function mintRootOrgNft (
100
114
address recipient ,
101
- string memory tokenURI_
115
+ WorkflowStructs.IPMetadata calldata orgIpMetadata
102
116
) external onlyStoryNFTFactory returns (uint256 rootOrgTokenId , address rootOrgIpId ) {
103
117
OrgNFTStorage storage $ = _getOrgNFTStorage ();
104
118
if ($.rootOrgIpId != address (0 )) revert OrgNFT__RootOrgNftAlreadyMinted ();
105
119
106
- (rootOrgTokenId, rootOrgIpId) = _mintAndRegisterIp (recipient, tokenURI_ );
120
+ (rootOrgTokenId, rootOrgIpId) = _mintAndRegisterIp (address ( this ), orgIpMetadata );
107
121
$.rootOrgIpId = rootOrgIpId;
122
+
123
+ _safeTransfer (address (this ), recipient, rootOrgTokenId);
108
124
}
109
125
110
126
/// @notice Mints a organization token, register it as an IP,
111
127
/// and makes the IP as a derivative of the root organization IP.
112
128
/// @dev This function is only callable by the OrgStoryNFTFactory contract.
113
129
/// @param recipient The address of the recipient of the minted organization token.
114
- /// @param tokenURI_ The URI of the minted organization token .
130
+ /// @param orgIpMetadata OPTIONAL. The desired metadata for the newly minted OrgNFT and registered IP .
115
131
/// @return orgTokenId The ID of the minted organization token.
116
132
/// @return orgIpId The ID of the organization IP.
117
133
function mintOrgNft (
118
134
address recipient ,
119
- string memory tokenURI_
135
+ WorkflowStructs.IPMetadata calldata orgIpMetadata
120
136
) external onlyStoryNFTFactory returns (uint256 orgTokenId , address orgIpId ) {
121
137
OrgNFTStorage storage $ = _getOrgNFTStorage ();
122
138
if ($.rootOrgIpId == address (0 )) revert OrgNFT__RootOrgNftNotMinted ();
123
139
124
140
// Mint the organization token and register it as an IP.
125
- (orgTokenId, orgIpId) = _mintAndRegisterIp (address (this ), tokenURI_ );
141
+ (orgTokenId, orgIpId) = _mintAndRegisterIp (address (this ), orgIpMetadata );
126
142
127
143
address [] memory parentIpIds = new address [](1 );
128
144
uint256 [] memory licenseTermsIds = new uint256 [](1 );
@@ -152,19 +168,33 @@ contract OrgNFT is IOrgNFT, ERC721URIStorageUpgradeable, AccessManagedUpgradeabl
152
168
153
169
/// @notice Mints a organization token and register it as an IP.
154
170
/// @param recipient The address of the recipient of the minted organization token.
155
- /// @param tokenURI_ The URI of the minted organization token .
171
+ /// @param orgIpMetadata OPTIONAL. The desired metadata for the newly minted OrgNFT and registered IP .
156
172
/// @return orgTokenId The ID of the minted organization token.
157
173
/// @return orgIpId The ID of the organization IP.
158
174
function _mintAndRegisterIp (
159
175
address recipient ,
160
- string memory tokenURI_
176
+ WorkflowStructs.IPMetadata calldata orgIpMetadata
161
177
) private returns (uint256 orgTokenId , address orgIpId ) {
162
178
OrgNFTStorage storage $ = _getOrgNFTStorage ();
163
179
orgTokenId = $.totalSupply++ ;
164
180
_safeMint (recipient, orgTokenId);
165
- _setTokenURI (orgTokenId, tokenURI_ );
181
+ _setTokenURI (orgTokenId, orgIpMetadata.nftMetadataURI );
166
182
orgIpId = IP_ASSET_REGISTRY.register (block .chainid , address (this ), orgTokenId);
167
183
184
+ // set the IP metadata if they are not empty
185
+ if (
186
+ keccak256 (abi.encodePacked (orgIpMetadata.ipMetadataURI)) != keccak256 ("" ) ||
187
+ orgIpMetadata.ipMetadataHash != bytes32 (0 ) ||
188
+ orgIpMetadata.nftMetadataHash != bytes32 (0 )
189
+ ) {
190
+ ICoreMetadataModule (CORE_METADATA_MODULE).setAll (
191
+ orgIpId,
192
+ orgIpMetadata.ipMetadataURI,
193
+ orgIpMetadata.ipMetadataHash,
194
+ orgIpMetadata.nftMetadataHash
195
+ );
196
+ }
197
+
168
198
emit OrgNFTMinted (recipient, address (this ), orgTokenId, orgIpId);
169
199
}
170
200
0 commit comments