1- # src/story_protcol_python_sdk/resources/License.py
2-
3- from ens .ens import HexStr
1+ from ens .ens import Address , HexStr
42from web3 import Web3
53
64from story_protocol_python_sdk .abi .IPAssetRegistry .IPAssetRegistry_client import (
2119from story_protocol_python_sdk .types .common import RevShareType
2220from story_protocol_python_sdk .utils .constants import ZERO_ADDRESS
2321from story_protocol_python_sdk .utils .license_terms import LicenseTerms
22+ from story_protocol_python_sdk .utils .licensing_config_data import (
23+ LicensingConfig ,
24+ LicensingConfigData ,
25+ )
2426from story_protocol_python_sdk .utils .transaction_utils import build_and_send_transaction
25- from story_protocol_python_sdk .utils .validation import get_revenue_share
27+ from story_protocol_python_sdk .utils .validation import (
28+ get_revenue_share ,
29+ validate_address ,
30+ )
2631
2732
2833class License :
@@ -183,7 +188,7 @@ def register_commercial_use_pil(
183188 currency : str ,
184189 royalty_policy : str | None = None ,
185190 tx_options : dict | None = None ,
186- ) -> dict | None :
191+ ) -> dict :
187192 """
188193 Convenient function to register a PIL commercial use license to the registry.
189194
@@ -214,14 +219,14 @@ def register_commercial_use_pil(
214219 complete_license_terms ,
215220 tx_options = tx_options ,
216221 )
217-
218- if not response ["tx_receipt" ]. logs :
219- return None
222+ tx_hash = response [ "tx_hash" ]
223+ if not response ["tx_receipt" ][ " logs" ] :
224+ return { "tx_hash" : tx_hash }
220225
221226 target_logs = self ._parse_tx_license_terms_registered_event (
222227 response ["tx_receipt" ]
223228 )
224- return {"tx_hash" : response [ " tx_hash" ] , "license_terms_id" : target_logs }
229+ return {"tx_hash" : tx_hash , "license_terms_id" : target_logs }
225230
226231 except Exception as e :
227232 raise e
@@ -233,7 +238,7 @@ def register_commercial_remix_pil(
233238 commercial_rev_share : int ,
234239 royalty_policy : str ,
235240 tx_options : dict | None = None ,
236- ) -> dict | None :
241+ ) -> dict :
237242 """
238243 Convenient function to register a PIL commercial remix license to the registry.
239244
@@ -267,13 +272,14 @@ def register_commercial_remix_pil(
267272 tx_options = tx_options ,
268273 )
269274
270- if not response ["tx_receipt" ].logs :
271- return None
275+ tx_hash = response ["tx_hash" ]
276+ if not response ["tx_receipt" ]["logs" ]:
277+ return {"tx_hash" : tx_hash }
272278
273279 target_logs = self ._parse_tx_license_terms_registered_event (
274280 response ["tx_receipt" ]
275281 )
276- return {"tx_hash" : response [ " tx_hash" ] , "license_terms_id" : target_logs }
282+ return {"tx_hash" : tx_hash , "license_terms_id" : target_logs }
277283
278284 except Exception as e :
279285 raise e
@@ -375,12 +381,8 @@ def mint_license_tokens(
375381 :return dict: A dictionary with the transaction hash and the license token IDs.
376382 """
377383 try :
378- if not self .web3 .is_address (license_template ):
379- raise ValueError (f'Address "{ license_template } " is invalid.' )
380-
381- if not self .web3 .is_address (receiver ):
382- raise ValueError (f'Address "{ receiver } " is invalid.' )
383-
384+ validate_address (license_template )
385+ validate_address (receiver )
384386 is_registered = self .ip_asset_registry_client .isRegistered (licensor_ip_id )
385387 if not is_registered :
386388 raise ValueError (
@@ -522,7 +524,7 @@ def set_licensing_config(
522524 self ,
523525 ip_id : str ,
524526 license_terms_id : int ,
525- licensing_config : dict ,
527+ licensing_config : LicensingConfig ,
526528 license_template : str | None = None ,
527529 tx_options : dict | None = None ,
528530 ) -> dict :
@@ -531,86 +533,36 @@ def set_licensing_config(
531533
532534 :param ip_id str: The address of the IP for which the configuration is being set.
533535 :param license_terms_id int: The ID of the license terms within the license template.
534- :param licensing_config dict: The licensing configuration for the license.
535- :param isSet bool: Whether the configuration is set or not.
536- :param mintingFee int: The minting fee to be paid when minting license tokens.
537- :param hookData str: The data to be used by the licensing hook.
538- :param licensingHook str: The hook contract address for the licensing module, or address(0) if none.
539- :param commercialRevShare int: The commercial revenue share percentage.
540- :param disabled bool: Whether the license is disabled or not.
541- :param expectMinimumGroupRewardShare int: The minimum percentage of the group's reward share (0-100%, as 100 * 10^6).
542- :param expectGroupRewardPool str: The address of the expected group reward pool.
536+ :param licensing_config `LicensingConfig`: The licensing configuration for the license.
543537 :param license_template str: [Optional] The address of the license template used. If not specified, config applies to all licenses.
544538 :param tx_options dict: [Optional] Transaction options.
545539 :return dict: A dictionary containing the transaction hash and success status.
546540 """
547541 try :
548- # Input validation
549- required_params = {
550- "isSet" ,
551- "mintingFee" ,
552- "hookData" ,
553- "licensingHook" ,
554- "commercialRevShare" ,
555- "disabled" ,
556- "expectMinimumGroupRewardShare" ,
557- "expectGroupRewardPool" ,
558- }
559-
560- # Check for missing parameters
561- missing_params = required_params - set (licensing_config .keys ())
562- if missing_params :
563- raise ValueError (
564- f"Missing required licensing_config parameters: { ', ' .join (missing_params )} . "
565- f"All parameters must be explicitly provided."
566- )
567-
568- licensing_config ["commercialRevShare" ] = (
569- self .license_terms_util .get_revenue_share (
570- licensing_config ["commercialRevShare" ]
571- )
542+ validated_licensing_config = LicensingConfigData .validate_license_config (
543+ self .module_registry_client , licensing_config
572544 )
573-
574- if licensing_config ["mintingFee" ] < 0 :
575- raise ValueError ("The minting fee must be greater than 0." )
576-
577- if not license_template :
578- license_template = ZERO_ADDRESS
545+ if license_template is None :
546+ license_template = self .license_template_client .contract .address
547+ else :
548+ validate_address (license_template )
579549
580550 if (
581551 license_template == ZERO_ADDRESS
582- and licensing_config ["commercialRevShare" ] != 0
552+ and validated_licensing_config ["commercialRevShare" ] != 0
583553 ):
584554 raise ValueError (
585555 "The license template cannot be zero address if commercial revenue share is not zero."
586556 )
587557
588- # Convert addresses to checksum format
589- ip_id = self .web3 .to_checksum_address (ip_id )
590- if license_template :
591- license_template = self .web3 .to_checksum_address (license_template )
592- licensing_config ["licensingHook" ] = self .web3 .to_checksum_address (
593- licensing_config ["licensingHook" ]
594- )
595- licensing_config ["expectGroupRewardPool" ] = self .web3 .to_checksum_address (
596- licensing_config ["expectGroupRewardPool" ]
597- )
598-
599558 # Check if IP is registered
600- if not self .ip_asset_registry_client .isRegistered (ip_id ):
559+ if not self .ip_asset_registry_client .isRegistered (validate_address ( ip_id ) ):
601560 raise ValueError (f"The licensor IP with id { ip_id } is not registered." )
602561
603562 # Check if license terms exist
604563 if not self .license_template_client .exists (license_terms_id ):
605564 raise ValueError (f"License terms id { license_terms_id } does not exist." )
606565
607- # Check if licensing hook is registered if provided
608- if licensing_config ["licensingHook" ] != ZERO_ADDRESS :
609- if not self .module_registry_client .isRegistered (
610- licensing_config ["licensingHook" ]
611- ):
612- raise ValueError ("The licensing hook is not registered." )
613-
614566 if license_template == ZERO_ADDRESS and license_terms_id != 0 :
615567 raise ValueError (
616568 "The license template is zero address but license terms id is not zero."
@@ -623,7 +575,7 @@ def set_licensing_config(
623575 ip_id ,
624576 license_template ,
625577 license_terms_id ,
626- licensing_config ,
578+ validated_licensing_config ,
627579 tx_options = tx_options ,
628580 )
629581
@@ -634,3 +586,35 @@ def set_licensing_config(
634586
635587 except Exception as e :
636588 raise ValueError (f"Failed to set licensing config: { str (e )} " )
589+
590+ def get_licensing_config (
591+ self ,
592+ ip_id : Address ,
593+ license_terms_id : int ,
594+ license_template : Address | None = None ,
595+ ) -> LicensingConfig :
596+ """
597+ Gets the licensing configuration for a specific license terms of an IP.
598+
599+ :param ip_id Address: The address of the IP for which the configuration is being retrieved.
600+ :param license_terms_id int: The ID of the license terms within the license template.
601+ :param license_template Address: [Optional] The address of the license template.
602+ Defaults to visit https://docs.story.foundation/docs/programmable-ip-license for more information if not provided.
603+ :return LicensingConfig: A dictionary containing the licensing configuration.
604+ """
605+ try :
606+ validate_address (ip_id )
607+
608+ if license_template is None :
609+ license_template = self .license_template_client .contract .address
610+ else :
611+ validate_address (license_template )
612+
613+ licensing_config = self .license_registry_client .getLicensingConfig (
614+ ip_id , license_template , license_terms_id
615+ )
616+
617+ return LicensingConfigData .from_tuple (licensing_config )
618+
619+ except Exception as e :
620+ raise ValueError (f"Failed to get licensing config: { str (e )} " )
0 commit comments