From 4c7c3c696db0c02b8607b65fed1c226fdf643be5 Mon Sep 17 00:00:00 2001 From: Bonnie Date: Tue, 5 Aug 2025 15:11:05 +0800 Subject: [PATCH 1/4] Add mypy library --- MANIFEST.in | 1 + mypy.ini | 24 ++++++++++++++++++++++++ setup.py | 1 + src/story_protocol_python_sdk/py.typed | 0 4 files changed, 26 insertions(+) create mode 100644 mypy.ini create mode 100644 src/story_protocol_python_sdk/py.typed diff --git a/MANIFEST.in b/MANIFEST.in index 2ace150..6704cb3 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -4,3 +4,4 @@ include requirements.txt recursive-include src *.py *.json recursive-include src/story_protocol_python_sdk/abi *.json recursive-include src/story_protocol_python_sdk/scripts *.json +include src/story_protocol_python_sdk/py.typed diff --git a/mypy.ini b/mypy.ini new file mode 100644 index 0000000..a80ed31 --- /dev/null +++ b/mypy.ini @@ -0,0 +1,24 @@ +[mypy] +python_version = 3.10 +warn_return_any = True +warn_unused_configs = True +disallow_untyped_defs = False +disallow_incomplete_defs = False +check_untyped_defs = True +disallow_untyped_decorators = False +no_implicit_optional = True +warn_redundant_casts = True +warn_unused_ignores = True +warn_no_return = True +warn_unreachable = True +strict_equality = True +exclude = story_protocol_python_sdk/abi|story_protocol_python_sdk/scripts +# Due to previous code having any return types, we need to disable this error code +disable_error_code = no-any-return + +# Ignore missing imports for external libraries +[mypy-web3.*] +ignore_missing_imports = True + +[mypy-ens.*] +ignore_missing_imports = True diff --git a/setup.py b/setup.py index eabcc7d..e562df3 100644 --- a/setup.py +++ b/setup.py @@ -10,6 +10,7 @@ package_dir={"": "src"}, install_requires=["web3>=7.0.0", "pytest", "python-dotenv", "base58"], include_package_data=True, # Ensure package data is included + package_data={"story_protocol_python_sdk": ["py.typed"]}, url="https://github.com/storyprotocol/python-sdk", license="MIT", author="Andrew Chung", diff --git a/src/story_protocol_python_sdk/py.typed b/src/story_protocol_python_sdk/py.typed new file mode 100644 index 0000000..e69de29 From f5811d9312432f14408095c526eeef4d28d24665 Mon Sep 17 00:00:00 2001 From: Bonnie Date: Tue, 5 Aug 2025 15:17:28 +0800 Subject: [PATCH 2/4] Fix type errors --- .../CoreMetadataViewModule_client.py | 1 - .../abi/DisputeModule/DisputeModule_client.py | 12 + .../abi/jsons/DisputeModule.json | 1583 +++++++---------- .../resources/Dispute.py | 12 +- .../resources/Group.py | 24 +- .../resources/IPAccount.py | 21 +- .../resources/IPAsset.py | 42 +- .../resources/License.py | 57 +- .../resources/NFTClient.py | 15 +- .../resources/Permission.py | 9 +- .../resources/Royalty.py | 12 +- .../resources/WIP.py | 12 +- .../scripts/config.json | 490 +++-- src/story_protocol_python_sdk/story_client.py | 18 +- .../utils/constants.py | 6 +- .../utils/license_terms.py | 3 +- src/story_protocol_python_sdk/utils/oov3.py | 4 +- src/story_protocol_python_sdk/utils/sign.py | 8 +- .../utils/transaction_utils.py | 6 +- tests/demo/demo.py | 39 +- .../test_integration_ip_account.py | 9 +- .../integration/test_integration_ip_asset.py | 8 +- tests/integration/test_integration_license.py | 2 + .../test_integration_nft_client.py | 63 - tests/integration/test_integration_royalty.py | 2 + tests/integration/test_integration_wip.py | 32 +- tests/unit/resources/test_royalty.py | 5 +- 27 files changed, 1090 insertions(+), 1405 deletions(-) diff --git a/src/story_protocol_python_sdk/abi/CoreMetadataViewModule/CoreMetadataViewModule_client.py b/src/story_protocol_python_sdk/abi/CoreMetadataViewModule/CoreMetadataViewModule_client.py index 8c14566..c0faf6f 100644 --- a/src/story_protocol_python_sdk/abi/CoreMetadataViewModule/CoreMetadataViewModule_client.py +++ b/src/story_protocol_python_sdk/abi/CoreMetadataViewModule/CoreMetadataViewModule_client.py @@ -15,7 +15,6 @@ def __init__(self, web3: Web3): ) with open(config_path, "r") as config_file: config = json.load(config_file) - contract_address = None for contract in config["contracts"]: if contract["contract_name"] == "CoreMetadataViewModule": diff --git a/src/story_protocol_python_sdk/abi/DisputeModule/DisputeModule_client.py b/src/story_protocol_python_sdk/abi/DisputeModule/DisputeModule_client.py index 2b8ae2f..58b9476 100644 --- a/src/story_protocol_python_sdk/abi/DisputeModule/DisputeModule_client.py +++ b/src/story_protocol_python_sdk/abi/DisputeModule/DisputeModule_client.py @@ -59,5 +59,17 @@ def build_resolveDispute_transaction(self, disputeId, data, tx_params): disputeId, data ).build_transaction(tx_params) + def tagIfRelatedIpInfringed(self, ipIdToTag, infringerDisputeId): + return self.contract.functions.tagIfRelatedIpInfringed( + ipIdToTag, infringerDisputeId + ).transact() + + def build_tagIfRelatedIpInfringed_transaction( + self, ipIdToTag, infringerDisputeId, tx_params + ): + return self.contract.functions.tagIfRelatedIpInfringed( + ipIdToTag, infringerDisputeId + ).build_transaction(tx_params) + def isWhitelistedDisputeTag(self, tag): return self.contract.functions.isWhitelistedDisputeTag(tag).call() diff --git a/src/story_protocol_python_sdk/abi/jsons/DisputeModule.json b/src/story_protocol_python_sdk/abi/jsons/DisputeModule.json index 1c58791..5053eb4 100644 --- a/src/story_protocol_python_sdk/abi/jsons/DisputeModule.json +++ b/src/story_protocol_python_sdk/abi/jsons/DisputeModule.json @@ -1,1286 +1,981 @@ [ { - "type": "constructor", "inputs": [ { + "internalType": "address", "name": "accessController", - "type": "address", - "internalType": "address" + "type": "address" }, { + "internalType": "address", "name": "ipAssetRegistry", - "type": "address", - "internalType": "address" + "type": "address" }, { + "internalType": "address", "name": "licenseRegistry", - "type": "address", - "internalType": "address" - } - ], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "ACCESS_CONTROLLER", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "address", - "internalType": "contract IAccessController" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "IN_DISPUTE", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "IP_ASSET_REGISTRY", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "address", - "internalType": "contract IIPAssetRegistry" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "LICENSE_REGISTRY", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "address", - "internalType": "contract ILicenseRegistry" - } + "type": "address" + }, + { "internalType": "address", "name": "ipGraphAcl", "type": "address" } ], - "stateMutability": "view" + "stateMutability": "nonpayable", + "type": "constructor" }, { - "type": "function", - "name": "UPGRADE_INTERFACE_VERSION", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "string", - "internalType": "string" - } + "inputs": [ + { "internalType": "address", "name": "ipAccount", "type": "address" } ], - "stateMutability": "view" + "name": "AccessControlled__NotIpAccount", + "type": "error" }, + { "inputs": [], "name": "AccessControlled__ZeroAddress", "type": "error" }, { - "type": "function", - "name": "__ProtocolPausable_init", "inputs": [ - { - "name": "accessManager", - "type": "address", - "internalType": "address" - } + { "internalType": "address", "name": "authority", "type": "address" } ], - "outputs": [], - "stateMutability": "nonpayable" + "name": "AccessManagedInvalidAuthority", + "type": "error" }, { - "type": "function", - "name": "arbitrationPolicies", "inputs": [ - { - "name": "ipId", - "type": "address", - "internalType": "address" - } + { "internalType": "address", "name": "caller", "type": "address" }, + { "internalType": "uint32", "name": "delay", "type": "uint32" } ], - "outputs": [ - { - "name": "policy", - "type": "address", - "internalType": "address" - } - ], - "stateMutability": "view" + "name": "AccessManagedRequiredDelay", + "type": "error" }, { - "type": "function", - "name": "arbitrationPolicyCooldown", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } + "inputs": [ + { "internalType": "address", "name": "caller", "type": "address" } ], - "stateMutability": "view" + "name": "AccessManagedUnauthorized", + "type": "error" }, { - "type": "function", - "name": "arbitrationRelayer", "inputs": [ - { - "name": "arbitrationPolicy", - "type": "address", - "internalType": "address" - } - ], - "outputs": [ - { - "name": "", - "type": "address", - "internalType": "address" - } + { "internalType": "address", "name": "target", "type": "address" } ], - "stateMutability": "view" + "name": "AddressEmptyCode", + "type": "error" }, { - "type": "function", - "name": "authority", "inputs": [], - "outputs": [ - { - "name": "", - "type": "address", - "internalType": "address" - } - ], - "stateMutability": "view" + "name": "DisputeModule__CannotBlacklistBaseArbitrationPolicy", + "type": "error" }, { - "type": "function", - "name": "baseArbitrationPolicy", "inputs": [], - "outputs": [ - { - "name": "", - "type": "address", - "internalType": "address" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "cancelDispute", - "inputs": [ - { - "name": "disputeId", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "data", - "type": "bytes", - "internalType": "bytes" - } - ], - "outputs": [], - "stateMutability": "nonpayable" + "name": "DisputeModule__DisputeAlreadyPropagated", + "type": "error" }, { - "type": "function", - "name": "disputeCounter", "inputs": [], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" + "name": "DisputeModule__DisputeWithoutInfringementTag", + "type": "error" }, { - "type": "function", - "name": "disputes", - "inputs": [ - { - "name": "disputeId", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [ - { - "name": "targetIpId", - "type": "address", - "internalType": "address" - }, - { - "name": "disputeInitiator", - "type": "address", - "internalType": "address" - }, - { - "name": "disputeTimestamp", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "arbitrationPolicy", - "type": "address", - "internalType": "address" - }, - { - "name": "disputeEvidenceHash", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "targetTag", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "currentTag", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "parentDisputeId", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" + "inputs": [], + "name": "DisputeModule__EvidenceHashAlreadyUsed", + "type": "error" }, + { "inputs": [], "name": "DisputeModule__NotAbleToResolve", "type": "error" }, { - "type": "function", - "name": "initialize", - "inputs": [ - { - "name": "accessManager", - "type": "address", - "internalType": "address" - } - ], - "outputs": [], - "stateMutability": "nonpayable" + "inputs": [], + "name": "DisputeModule__NotAllowedToWhitelist", + "type": "error" }, { - "type": "function", - "name": "isConsumingScheduledOp", "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes4", - "internalType": "bytes4" - } - ], - "stateMutability": "view" + "name": "DisputeModule__NotArbitrationRelayer", + "type": "error" }, { - "type": "function", - "name": "isIpTagged", - "inputs": [ - { - "name": "ipId", - "type": "address", - "internalType": "address" - } - ], - "outputs": [ - { - "name": "", - "type": "bool", - "internalType": "bool" - } - ], - "stateMutability": "view" + "inputs": [], + "name": "DisputeModule__NotDerivativeOrGroupIp", + "type": "error" }, { - "type": "function", - "name": "isWhitelistedArbitrationPolicy", - "inputs": [ - { - "name": "arbitrationPolicy", - "type": "address", - "internalType": "address" - } - ], - "outputs": [ - { - "name": "allowed", - "type": "bool", - "internalType": "bool" - } - ], - "stateMutability": "view" + "inputs": [], + "name": "DisputeModule__NotDisputeInitiator", + "type": "error" }, + { "inputs": [], "name": "DisputeModule__NotInDisputeState", "type": "error" }, + { "inputs": [], "name": "DisputeModule__NotRegisteredIpId", "type": "error" }, { - "type": "function", - "name": "isWhitelistedDisputeTag", - "inputs": [ - { - "name": "tag", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "outputs": [ - { - "name": "allowed", - "type": "bool", - "internalType": "bool" - } - ], - "stateMutability": "view" + "inputs": [], + "name": "DisputeModule__NotWhitelistedArbitrationPolicy", + "type": "error" }, { - "type": "function", - "name": "multicall", - "inputs": [ - { - "name": "data", - "type": "bytes[]", - "internalType": "bytes[]" - } - ], - "outputs": [ - { - "name": "results", - "type": "bytes[]", - "internalType": "bytes[]" - } - ], - "stateMutability": "nonpayable" + "inputs": [], + "name": "DisputeModule__NotWhitelistedDisputeTag", + "type": "error" }, { - "type": "function", - "name": "name", "inputs": [], - "outputs": [ - { - "name": "", - "type": "string", - "internalType": "string" - } - ], - "stateMutability": "view" + "name": "DisputeModule__RelatedDisputeNotResolved", + "type": "error" }, { - "type": "function", - "name": "nextArbitrationPolicies", - "inputs": [ - { - "name": "ipId", - "type": "address", - "internalType": "address" - } - ], - "outputs": [ - { - "name": "policy", - "type": "address", - "internalType": "address" - } - ], - "stateMutability": "view" + "inputs": [], + "name": "DisputeModule__ZeroAccessController", + "type": "error" }, + { "inputs": [], "name": "DisputeModule__ZeroAccessManager", "type": "error" }, { - "type": "function", - "name": "nextArbitrationUpdateTimestamps", - "inputs": [ - { - "name": "ipId", - "type": "address", - "internalType": "address" - } - ], - "outputs": [ - { - "name": "timestamp", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" + "inputs": [], + "name": "DisputeModule__ZeroArbitrationPolicy", + "type": "error" }, { - "type": "function", - "name": "pause", "inputs": [], - "outputs": [], - "stateMutability": "nonpayable" + "name": "DisputeModule__ZeroArbitrationPolicyCooldown", + "type": "error" }, { - "type": "function", - "name": "paused", "inputs": [], - "outputs": [ - { - "name": "", - "type": "bool", - "internalType": "bool" - } - ], - "stateMutability": "view" + "name": "DisputeModule__ZeroDisputeEvidenceHash", + "type": "error" }, + { "inputs": [], "name": "DisputeModule__ZeroDisputeTag", "type": "error" }, { - "type": "function", - "name": "proxiableUUID", "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" + "name": "DisputeModule__ZeroIPAssetRegistry", + "type": "error" }, + { "inputs": [], "name": "DisputeModule__ZeroIPGraphACL", "type": "error" }, { - "type": "function", - "name": "raiseDispute", - "inputs": [ - { - "name": "targetIpId", - "type": "address", - "internalType": "address" - }, - { - "name": "disputeEvidenceHash", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "targetTag", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "data", - "type": "bytes", - "internalType": "bytes" - } - ], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "nonpayable" + "inputs": [], + "name": "DisputeModule__ZeroLicenseRegistry", + "type": "error" }, { - "type": "function", - "name": "resolveDispute", "inputs": [ - { - "name": "disputeId", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "data", - "type": "bytes", - "internalType": "bytes" - } + { "internalType": "address", "name": "implementation", "type": "address" } ], - "outputs": [], - "stateMutability": "nonpayable" + "name": "ERC1967InvalidImplementation", + "type": "error" }, + { "inputs": [], "name": "ERC1967NonPayable", "type": "error" }, + { "inputs": [], "name": "EnforcedPause", "type": "error" }, + { "inputs": [], "name": "ExpectedPause", "type": "error" }, + { "inputs": [], "name": "FailedCall", "type": "error" }, + { "inputs": [], "name": "InvalidInitialization", "type": "error" }, + { "inputs": [], "name": "NotInitializing", "type": "error" }, + { "inputs": [], "name": "ReentrancyGuardReentrantCall", "type": "error" }, + { "inputs": [], "name": "UUPSUnauthorizedCallContext", "type": "error" }, { - "type": "function", - "name": "setArbitrationPolicy", "inputs": [ - { - "name": "ipId", - "type": "address", - "internalType": "address" - }, - { - "name": "nextArbitrationPolicy", - "type": "address", - "internalType": "address" - } + { "internalType": "bytes32", "name": "slot", "type": "bytes32" } ], - "outputs": [], - "stateMutability": "nonpayable" + "name": "UUPSUnsupportedProxiableUUID", + "type": "error" }, { - "type": "function", - "name": "setArbitrationPolicyCooldown", + "anonymous": false, "inputs": [ { + "indexed": false, + "internalType": "uint256", "name": "cooldown", - "type": "uint256", - "internalType": "uint256" + "type": "uint256" } ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "setArbitrationRelayer", - "inputs": [ - { - "name": "arbitrationPolicy", - "type": "address", - "internalType": "address" - }, - { - "name": "arbPolicyRelayer", - "type": "address", - "internalType": "address" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "setAuthority", - "inputs": [ - { - "name": "newAuthority", - "type": "address", - "internalType": "address" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "setBaseArbitrationPolicy", - "inputs": [ - { - "name": "arbitrationPolicy", - "type": "address", - "internalType": "address" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "setDisputeJudgement", - "inputs": [ - { - "name": "disputeId", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "decision", - "type": "bool", - "internalType": "bool" - }, - { - "name": "data", - "type": "bytes", - "internalType": "bytes" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "supportsInterface", - "inputs": [ - { - "name": "interfaceId", - "type": "bytes4", - "internalType": "bytes4" - } - ], - "outputs": [ - { - "name": "", - "type": "bool", - "internalType": "bool" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "tagDerivativeIfParentInfringed", - "inputs": [ - { - "name": "parentIpId", - "type": "address", - "internalType": "address" - }, - { - "name": "derivativeIpId", - "type": "address", - "internalType": "address" - }, - { - "name": "parentDisputeId", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "unpause", - "inputs": [], - "outputs": [], - "stateMutability": "nonpayable" + "name": "ArbitrationPolicyCooldownUpdated", + "type": "event" }, { - "type": "function", - "name": "updateActiveArbitrationPolicy", + "anonymous": false, "inputs": [ { + "indexed": false, + "internalType": "address", "name": "ipId", - "type": "address", - "internalType": "address" - } - ], - "outputs": [ + "type": "address" + }, { + "indexed": false, + "internalType": "address", "name": "arbitrationPolicy", - "type": "address", - "internalType": "address" - } - ], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "upgradeToAndCall", - "inputs": [ - { - "name": "newImplementation", - "type": "address", - "internalType": "address" + "type": "address" }, { - "name": "data", - "type": "bytes", - "internalType": "bytes" + "indexed": false, + "internalType": "uint256", + "name": "nextArbitrationUpdateTimestamp", + "type": "uint256" } ], - "outputs": [], - "stateMutability": "payable" + "name": "ArbitrationPolicySet", + "type": "event" }, { - "type": "function", - "name": "whitelistArbitrationPolicy", + "anonymous": false, "inputs": [ { + "indexed": false, + "internalType": "address", "name": "arbitrationPolicy", - "type": "address", - "internalType": "address" + "type": "address" }, { + "indexed": false, + "internalType": "bool", "name": "allowed", - "type": "bool", - "internalType": "bool" + "type": "bool" } ], - "outputs": [], - "stateMutability": "nonpayable" + "name": "ArbitrationPolicyWhitelistUpdated", + "type": "event" }, { - "type": "function", - "name": "whitelistDisputeTag", + "anonymous": false, "inputs": [ { - "name": "tag", - "type": "bytes32", - "internalType": "bytes32" + "indexed": false, + "internalType": "address", + "name": "arbitrationPolicy", + "type": "address" }, { - "name": "allowed", - "type": "bool", - "internalType": "bool" + "indexed": false, + "internalType": "address", + "name": "arbitrationRelayer", + "type": "address" } ], - "outputs": [], - "stateMutability": "nonpayable" + "name": "ArbitrationRelayerUpdated", + "type": "event" }, { - "type": "event", - "name": "ArbitrationPolicyCooldownUpdated", + "anonymous": false, "inputs": [ { - "name": "cooldown", - "type": "uint256", "indexed": false, - "internalType": "uint256" + "internalType": "address", + "name": "authority", + "type": "address" } ], - "anonymous": false + "name": "AuthorityUpdated", + "type": "event" }, { - "type": "event", - "name": "ArbitrationPolicySet", + "anonymous": false, "inputs": [ { - "name": "ipId", - "type": "address", "indexed": false, - "internalType": "address" - }, - { + "internalType": "address", "name": "arbitrationPolicy", - "type": "address", - "indexed": false, - "internalType": "address" - }, - { - "name": "nextArbitrationUpdateTimestamp", - "type": "uint256", - "indexed": false, - "internalType": "uint256" + "type": "address" } ], - "anonymous": false + "name": "DefaultArbitrationPolicyUpdated", + "type": "event" }, { - "type": "event", - "name": "ArbitrationPolicyWhitelistUpdated", + "anonymous": false, "inputs": [ { - "name": "arbitrationPolicy", - "type": "address", "indexed": false, - "internalType": "address" + "internalType": "uint256", + "name": "disputeId", + "type": "uint256" }, { - "name": "allowed", - "type": "bool", "indexed": false, - "internalType": "bool" + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "anonymous": false + "name": "DisputeCancelled", + "type": "event" }, { - "type": "event", - "name": "ArbitrationRelayerUpdated", + "anonymous": false, "inputs": [ { - "name": "arbitrationPolicy", - "type": "address", "indexed": false, - "internalType": "address" + "internalType": "uint256", + "name": "disputeId", + "type": "uint256" }, { - "name": "arbitrationRelayer", - "type": "address", "indexed": false, - "internalType": "address" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "AuthorityUpdated", - "inputs": [ + "internalType": "bool", + "name": "decision", + "type": "bool" + }, { - "name": "authority", - "type": "address", "indexed": false, - "internalType": "address" + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "anonymous": false + "name": "DisputeJudgementSet", + "type": "event" }, { - "type": "event", - "name": "DefaultArbitrationPolicyUpdated", + "anonymous": false, "inputs": [ { - "name": "arbitrationPolicy", - "type": "address", "indexed": false, - "internalType": "address" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "DerivativeTaggedOnParentInfringement", - "inputs": [ + "internalType": "uint256", + "name": "disputeId", + "type": "uint256" + }, { - "name": "parentIpId", - "type": "address", "indexed": false, - "internalType": "address" + "internalType": "address", + "name": "targetIpId", + "type": "address" }, { - "name": "derivativeIpId", - "type": "address", "indexed": false, - "internalType": "address" + "internalType": "address", + "name": "disputeInitiator", + "type": "address" }, { - "name": "parentDisputeId", - "type": "uint256", "indexed": false, - "internalType": "uint256" + "internalType": "uint256", + "name": "disputeTimestamp", + "type": "uint256" }, { - "name": "tag", - "type": "bytes32", "indexed": false, - "internalType": "bytes32" + "internalType": "address", + "name": "arbitrationPolicy", + "type": "address" }, { - "name": "disputeTimestamp", - "type": "uint256", "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "DisputeCancelled", - "inputs": [ + "internalType": "bytes32", + "name": "disputeEvidenceHash", + "type": "bytes32" + }, { - "name": "disputeId", - "type": "uint256", "indexed": false, - "internalType": "uint256" + "internalType": "bytes32", + "name": "targetTag", + "type": "bytes32" }, { - "name": "data", - "type": "bytes", "indexed": false, - "internalType": "bytes" + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "anonymous": false + "name": "DisputeRaised", + "type": "event" }, { - "type": "event", - "name": "DisputeJudgementSet", + "anonymous": false, "inputs": [ { - "name": "disputeId", - "type": "uint256", "indexed": false, - "internalType": "uint256" + "internalType": "uint256", + "name": "disputeId", + "type": "uint256" }, { - "name": "decision", - "type": "bool", "indexed": false, - "internalType": "bool" - }, - { + "internalType": "bytes", "name": "data", - "type": "bytes", - "indexed": false, - "internalType": "bytes" + "type": "bytes" } ], - "anonymous": false + "name": "DisputeResolved", + "type": "event" }, { - "type": "event", - "name": "DisputeRaised", + "anonymous": false, "inputs": [ { - "name": "disputeId", - "type": "uint256", "indexed": false, - "internalType": "uint256" - }, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { - "name": "targetIpId", - "type": "address", "indexed": false, - "internalType": "address" + "internalType": "uint256", + "name": "disputeId", + "type": "uint256" }, { - "name": "disputeInitiator", - "type": "address", "indexed": false, - "internalType": "address" + "internalType": "address", + "name": "infringingIpId", + "type": "address" }, { - "name": "disputeTimestamp", - "type": "uint256", "indexed": false, - "internalType": "uint256" + "internalType": "address", + "name": "ipIdToTag", + "type": "address" }, { - "name": "arbitrationPolicy", - "type": "address", "indexed": false, - "internalType": "address" + "internalType": "uint256", + "name": "infringerDisputeId", + "type": "uint256" }, { - "name": "disputeEvidenceHash", - "type": "bytes32", "indexed": false, - "internalType": "bytes32" + "internalType": "bytes32", + "name": "tag", + "type": "bytes32" }, { - "name": "targetTag", - "type": "bytes32", "indexed": false, - "internalType": "bytes32" - }, + "internalType": "uint256", + "name": "disputeTimestamp", + "type": "uint256" + } + ], + "name": "IpTaggedOnRelatedIpInfringement", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { - "name": "data", - "type": "bytes", "indexed": false, - "internalType": "bytes" + "internalType": "address", + "name": "account", + "type": "address" } ], - "anonymous": false + "name": "Paused", + "type": "event" }, { - "type": "event", - "name": "DisputeResolved", + "anonymous": false, "inputs": [ { - "name": "disputeId", - "type": "uint256", "indexed": false, - "internalType": "uint256" + "internalType": "bytes32", + "name": "tag", + "type": "bytes32" }, { - "name": "data", - "type": "bytes", "indexed": false, - "internalType": "bytes" + "internalType": "bool", + "name": "allowed", + "type": "bool" } ], - "anonymous": false + "name": "TagWhitelistUpdated", + "type": "event" }, { - "type": "event", - "name": "Initialized", + "anonymous": false, "inputs": [ { - "name": "version", - "type": "uint64", "indexed": false, - "internalType": "uint64" + "internalType": "address", + "name": "account", + "type": "address" } ], - "anonymous": false + "name": "Unpaused", + "type": "event" }, { - "type": "event", - "name": "Paused", + "anonymous": false, "inputs": [ { - "name": "account", - "type": "address", - "indexed": false, - "internalType": "address" + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" } ], - "anonymous": false + "name": "Upgraded", + "type": "event" }, { - "type": "event", - "name": "TagWhitelistUpdated", - "inputs": [ - { - "name": "tag", - "type": "bytes32", - "indexed": false, - "internalType": "bytes32" - }, + "inputs": [], + "name": "ACCESS_CONTROLLER", + "outputs": [ { - "name": "allowed", - "type": "bool", - "indexed": false, - "internalType": "bool" + "internalType": "contract IAccessController", + "name": "", + "type": "address" } ], - "anonymous": false + "stateMutability": "view", + "type": "function" }, { - "type": "event", - "name": "Unpaused", - "inputs": [ + "inputs": [], + "name": "GROUP_IP_ASSET_REGISTRY", + "outputs": [ { - "name": "account", - "type": "address", - "indexed": false, - "internalType": "address" + "internalType": "contract IGroupIPAssetRegistry", + "name": "", + "type": "address" } ], - "anonymous": false + "stateMutability": "view", + "type": "function" }, { - "type": "event", - "name": "Upgraded", - "inputs": [ + "inputs": [], + "name": "IN_DISPUTE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "IP_ASSET_REGISTRY", + "outputs": [ { - "name": "implementation", - "type": "address", - "indexed": true, - "internalType": "address" + "internalType": "contract IIPAssetRegistry", + "name": "", + "type": "address" } ], - "anonymous": false + "stateMutability": "view", + "type": "function" }, { - "type": "error", - "name": "AccessControlled__NotIpAccount", - "inputs": [ + "inputs": [], + "name": "IP_GRAPH_ACL", + "outputs": [ + { "internalType": "contract IPGraphACL", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LICENSE_REGISTRY", + "outputs": [ { - "name": "ipAccount", - "type": "address", - "internalType": "address" + "internalType": "contract ILicenseRegistry", + "name": "", + "type": "address" } - ] + ], + "stateMutability": "view", + "type": "function" }, { - "type": "error", - "name": "AccessControlled__ZeroAddress", - "inputs": [] + "inputs": [], + "name": "UPGRADE_INTERFACE_VERSION", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" }, { - "type": "error", - "name": "AccessManagedInvalidAuthority", "inputs": [ - { - "name": "authority", - "type": "address", - "internalType": "address" - } - ] + { "internalType": "address", "name": "accessManager", "type": "address" } + ], + "name": "__ProtocolPausable_init", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "type": "error", - "name": "AccessManagedRequiredDelay", "inputs": [ - { - "name": "caller", - "type": "address", - "internalType": "address" - }, - { - "name": "delay", - "type": "uint32", - "internalType": "uint32" - } - ] + { "internalType": "address", "name": "ipId", "type": "address" } + ], + "name": "arbitrationPolicies", + "outputs": [ + { "internalType": "address", "name": "policy", "type": "address" } + ], + "stateMutability": "view", + "type": "function" }, { - "type": "error", - "name": "AccessManagedUnauthorized", - "inputs": [ - { - "name": "caller", - "type": "address", - "internalType": "address" - } - ] + "inputs": [], + "name": "arbitrationPolicyCooldown", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" }, { - "type": "error", - "name": "AddressEmptyCode", "inputs": [ { - "name": "target", - "type": "address", - "internalType": "address" + "internalType": "address", + "name": "arbitrationPolicy", + "type": "address" } - ] - }, - { - "type": "error", - "name": "DisputeModule__CannotBlacklistBaseArbitrationPolicy", - "inputs": [] + ], + "name": "arbitrationRelayer", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" }, { - "type": "error", - "name": "DisputeModule__DisputeAlreadyPropagated", - "inputs": [] + "inputs": [], + "name": "authority", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" }, { - "type": "error", - "name": "DisputeModule__NotAbleToResolve", - "inputs": [] + "inputs": [], + "name": "baseArbitrationPolicy", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" }, { - "type": "error", - "name": "DisputeModule__NotAllowedToWhitelist", - "inputs": [] + "inputs": [ + { "internalType": "uint256", "name": "disputeId", "type": "uint256" }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "cancelDispute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "type": "error", - "name": "DisputeModule__NotArbitrationRelayer", - "inputs": [] + "inputs": [], + "name": "disputeCounter", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" }, { - "type": "error", - "name": "DisputeModule__NotDerivative", - "inputs": [] + "inputs": [ + { "internalType": "uint256", "name": "disputeId", "type": "uint256" } + ], + "name": "disputes", + "outputs": [ + { "internalType": "address", "name": "targetIpId", "type": "address" }, + { + "internalType": "address", + "name": "disputeInitiator", + "type": "address" + }, + { + "internalType": "uint256", + "name": "disputeTimestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "arbitrationPolicy", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "disputeEvidenceHash", + "type": "bytes32" + }, + { "internalType": "bytes32", "name": "targetTag", "type": "bytes32" }, + { "internalType": "bytes32", "name": "currentTag", "type": "bytes32" }, + { + "internalType": "uint256", + "name": "infringerDisputeId", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" }, { - "type": "error", - "name": "DisputeModule__NotDisputeInitiator", - "inputs": [] + "inputs": [ + { "internalType": "address", "name": "accessManager", "type": "address" } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "type": "error", - "name": "DisputeModule__NotInDisputeState", - "inputs": [] + "inputs": [], + "name": "isConsumingScheduledOp", + "outputs": [{ "internalType": "bytes4", "name": "", "type": "bytes4" }], + "stateMutability": "view", + "type": "function" }, { - "type": "error", - "name": "DisputeModule__NotRegisteredIpId", - "inputs": [] + "inputs": [ + { "internalType": "address", "name": "ipId", "type": "address" } + ], + "name": "isIpTagged", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" }, { - "type": "error", - "name": "DisputeModule__NotWhitelistedArbitrationPolicy", - "inputs": [] + "inputs": [ + { + "internalType": "address", + "name": "arbitrationPolicy", + "type": "address" + } + ], + "name": "isWhitelistedArbitrationPolicy", + "outputs": [{ "internalType": "bool", "name": "allowed", "type": "bool" }], + "stateMutability": "view", + "type": "function" }, { - "type": "error", - "name": "DisputeModule__NotWhitelistedDisputeTag", - "inputs": [] + "inputs": [{ "internalType": "bytes32", "name": "tag", "type": "bytes32" }], + "name": "isWhitelistedDisputeTag", + "outputs": [{ "internalType": "bool", "name": "allowed", "type": "bool" }], + "stateMutability": "view", + "type": "function" }, { - "type": "error", - "name": "DisputeModule__ParentDisputeNotResolved", - "inputs": [] + "inputs": [ + { "internalType": "bytes[]", "name": "data", "type": "bytes[]" } + ], + "name": "multicall", + "outputs": [ + { "internalType": "bytes[]", "name": "results", "type": "bytes[]" } + ], + "stateMutability": "nonpayable", + "type": "function" }, { - "type": "error", - "name": "DisputeModule__ParentIpIdMismatch", - "inputs": [] + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" }, { - "type": "error", - "name": "DisputeModule__ParentNotTagged", - "inputs": [] + "inputs": [ + { "internalType": "address", "name": "ipId", "type": "address" } + ], + "name": "nextArbitrationPolicies", + "outputs": [ + { "internalType": "address", "name": "policy", "type": "address" } + ], + "stateMutability": "view", + "type": "function" }, { - "type": "error", - "name": "DisputeModule__ZeroAccessController", - "inputs": [] + "inputs": [ + { "internalType": "address", "name": "ipId", "type": "address" } + ], + "name": "nextArbitrationUpdateTimestamps", + "outputs": [ + { "internalType": "uint256", "name": "timestamp", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" }, { - "type": "error", - "name": "DisputeModule__ZeroAccessManager", - "inputs": [] + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "type": "error", - "name": "DisputeModule__ZeroArbitrationPolicy", - "inputs": [] + "inputs": [], + "name": "paused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" }, { - "type": "error", - "name": "DisputeModule__ZeroArbitrationPolicyCooldown", - "inputs": [] + "inputs": [], + "name": "proxiableUUID", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" }, { - "type": "error", - "name": "DisputeModule__ZeroDisputeEvidenceHash", - "inputs": [] + "inputs": [ + { "internalType": "address", "name": "targetIpId", "type": "address" }, + { + "internalType": "bytes32", + "name": "disputeEvidenceHash", + "type": "bytes32" + }, + { "internalType": "bytes32", "name": "targetTag", "type": "bytes32" }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "raiseDispute", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" }, { - "type": "error", - "name": "DisputeModule__ZeroDisputeTag", - "inputs": [] + "inputs": [ + { "internalType": "uint256", "name": "disputeId", "type": "uint256" }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "resolveDispute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "type": "error", - "name": "DisputeModule__ZeroIPAssetRegistry", - "inputs": [] + "inputs": [ + { "internalType": "address", "name": "ipId", "type": "address" }, + { + "internalType": "address", + "name": "nextArbitrationPolicy", + "type": "address" + } + ], + "name": "setArbitrationPolicy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "type": "error", - "name": "DisputeModule__ZeroLicenseRegistry", - "inputs": [] + "inputs": [ + { "internalType": "uint256", "name": "cooldown", "type": "uint256" } + ], + "name": "setArbitrationPolicyCooldown", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "type": "error", - "name": "ERC1967InvalidImplementation", "inputs": [ { - "name": "implementation", - "type": "address", - "internalType": "address" + "internalType": "address", + "name": "arbitrationPolicy", + "type": "address" + }, + { + "internalType": "address", + "name": "arbPolicyRelayer", + "type": "address" } - ] + ], + "name": "setArbitrationRelayer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "type": "error", - "name": "ERC1967NonPayable", - "inputs": [] + "inputs": [ + { "internalType": "address", "name": "newAuthority", "type": "address" } + ], + "name": "setAuthority", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "type": "error", - "name": "EnforcedPause", - "inputs": [] + "inputs": [ + { + "internalType": "address", + "name": "arbitrationPolicy", + "type": "address" + } + ], + "name": "setBaseArbitrationPolicy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "type": "error", - "name": "ExpectedPause", - "inputs": [] + "inputs": [ + { "internalType": "uint256", "name": "disputeId", "type": "uint256" }, + { "internalType": "bool", "name": "decision", "type": "bool" }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "setDisputeJudgement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "type": "error", - "name": "FailedInnerCall", - "inputs": [] + "inputs": [ + { "internalType": "bytes4", "name": "interfaceId", "type": "bytes4" } + ], + "name": "supportsInterface", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" }, { - "type": "error", - "name": "InvalidInitialization", - "inputs": [] + "inputs": [ + { "internalType": "address", "name": "ipIdToTag", "type": "address" }, + { + "internalType": "uint256", + "name": "infringerDisputeId", + "type": "uint256" + } + ], + "name": "tagIfRelatedIpInfringed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "type": "error", - "name": "NotInitializing", - "inputs": [] + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "type": "error", - "name": "ReentrancyGuardReentrantCall", - "inputs": [] + "inputs": [ + { "internalType": "address", "name": "ipId", "type": "address" } + ], + "name": "updateActiveArbitrationPolicy", + "outputs": [ + { + "internalType": "address", + "name": "arbitrationPolicy", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" }, { - "type": "error", - "name": "UUPSUnauthorizedCallContext", - "inputs": [] + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" }, { - "type": "error", - "name": "UUPSUnsupportedProxiableUUID", "inputs": [ { - "name": "slot", - "type": "bytes32", - "internalType": "bytes32" - } - ] + "internalType": "address", + "name": "arbitrationPolicy", + "type": "address" + }, + { "internalType": "bool", "name": "allowed", "type": "bool" } + ], + "name": "whitelistArbitrationPolicy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "tag", "type": "bytes32" }, + { "internalType": "bool", "name": "allowed", "type": "bool" } + ], + "name": "whitelistDisputeTag", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" } ] diff --git a/src/story_protocol_python_sdk/resources/Dispute.py b/src/story_protocol_python_sdk/resources/Dispute.py index 0fc7355..6859e80 100644 --- a/src/story_protocol_python_sdk/resources/Dispute.py +++ b/src/story_protocol_python_sdk/resources/Dispute.py @@ -55,7 +55,7 @@ def raise_dispute( cid: str, liveness: int, bond: int, - tx_options: dict = None, + tx_options: dict | None = None, ) -> dict: """ Raises a dispute on a given IP ID. @@ -132,7 +132,7 @@ def raise_dispute( raise ValueError(f"Failed to raise dispute: {str(e)}") def cancel_dispute( - self, dispute_id: int, data: str = "0x", tx_options: dict = None + self, dispute_id: int, data: str = "0x", tx_options: dict | None = None ) -> dict: """ Cancels an ongoing dispute. @@ -158,7 +158,7 @@ def cancel_dispute( raise ValueError(f"Failed to cancel dispute: {str(e)}") def resolve_dispute( - self, dispute_id: int, data: str, tx_options: dict = None + self, dispute_id: int, data: str, tx_options: dict | None = None ) -> dict: """ Resolves a dispute after it has been judged. @@ -184,7 +184,7 @@ def resolve_dispute( raise ValueError(f"Failed to resolve dispute: {str(e)}") def tag_if_related_ip_infringed( - self, infringement_tags: list, tx_options: dict = None + self, infringement_tags: list, tx_options: dict | None = None ) -> list: """ Tags a derivative if a parent has been tagged with an infringement tag. @@ -217,7 +217,7 @@ def tag_if_related_ip_infringed( except Exception as e: raise ValueError(f"Failed to tag related IP infringed: {str(e)}") - def _parse_tx_dispute_raised_event(self, tx_receipt: dict) -> int: + def _parse_tx_dispute_raised_event(self, tx_receipt: dict) -> int | None: """ Parse the DisputeRaised event from a transaction receipt. @@ -240,7 +240,7 @@ def dispute_assertion( assertion_id: str, counter_evidence_cid: str, ip_id: str, - tx_options: dict = None, + tx_options: dict | None = None, ) -> dict: """ Counters a dispute that was raised by another party on an IP using counter evidence. diff --git a/src/story_protocol_python_sdk/resources/Group.py b/src/story_protocol_python_sdk/resources/Group.py index dba882e..9776d19 100644 --- a/src/story_protocol_python_sdk/resources/Group.py +++ b/src/story_protocol_python_sdk/resources/Group.py @@ -57,7 +57,7 @@ def __init__(self, web3: Web3, account, chain_id: int): self.license_terms_util = LicenseTerms(web3) self.sign_util = Sign(web3, self.chain_id, self.account) - def register_group(self, group_pool: str, tx_options: dict = None) -> dict: + def register_group(self, group_pool: str, tx_options: dict | None = None) -> dict: """ Registers a Group IPA. @@ -85,7 +85,7 @@ def register_group(self, group_pool: str, tx_options: dict = None) -> dict: raise ValueError(f"Failed to register group: {str(e)}") def register_group_and_attach_license( - self, group_pool: str, license_data: dict, tx_options: dict = None + self, group_pool: str, license_data: dict, tx_options: dict | None = None ) -> dict: """ Register a group IP with a group reward pool and attach license terms to the group IP. @@ -124,11 +124,11 @@ def mint_and_register_ip_and_attach_license_and_add_to_group( spg_nft_contract: str, license_data: list, max_allowed_reward_share: int, - ip_metadata: dict = None, - recipient: str = None, + ip_metadata: dict | None = None, + recipient: str | None = None, allow_duplicates: bool = True, - deadline: int = None, - tx_options: dict = None, + deadline: int | None = None, + tx_options: dict | None = None, ) -> dict: """ Mint an NFT from a SPGNFT collection, register it with metadata as an IP, @@ -237,9 +237,9 @@ def register_ip_and_attach_license_and_add_to_group( token_id: int, license_data: list, max_allowed_reward_share: int, - ip_metadata: dict = None, - deadline: int = None, - tx_options: dict = None, + ip_metadata: dict | None = None, + deadline: int | None = None, + tx_options: dict | None = None, ) -> dict: """ Register an NFT as IP with metadata, attach license terms to the registered IP, @@ -380,7 +380,7 @@ def register_group_and_attach_license_and_add_ips( ip_ids: list, license_data: dict, max_allowed_reward_share: int, - tx_options: dict = None, + tx_options: dict | None = None, ) -> dict: """ Register a group IP with a group reward pool, attach license terms to the group IP, @@ -446,7 +446,7 @@ def collect_and_distribute_group_royalties( group_ip_id: str, currency_tokens: list, member_ip_ids: list, - tx_options: dict = None, + tx_options: dict | None = None, ) -> dict: """ Collect royalties for the entire group and distribute the rewards to each member IP's royalty vault. @@ -581,7 +581,7 @@ def _get_license_data(self, license_data: list) -> list: return result - def _get_ip_metadata(self, ip_metadata: dict = None) -> dict: + def _get_ip_metadata(self, ip_metadata: dict | None = None) -> dict: """ Process IP metadata into the format expected by the contracts. diff --git a/src/story_protocol_python_sdk/resources/IPAccount.py b/src/story_protocol_python_sdk/resources/IPAccount.py index facab3c..996f85b 100644 --- a/src/story_protocol_python_sdk/resources/IPAccount.py +++ b/src/story_protocol_python_sdk/resources/IPAccount.py @@ -74,7 +74,12 @@ def _validate_transaction_params(self, ip_id: str, to: str): raise ValueError(f"The IP id {ip_id} is not registered.") def execute( - self, to: str, value: int, ip_id: str, data: str, tx_options: dict = None + self, + to: str, + value: int, + ip_id: str, + data: str, + tx_options: dict | None = None, ) -> dict: """Execute a transaction from the IP Account. @@ -109,9 +114,9 @@ def execute_with_sig( data: str, signer: str, deadline: int, - signature: str, + signature: bytes, value: int = 0, - tx_options: dict = None, + tx_options: dict | None = None, ) -> dict: """Execute a signed transaction from the IP Account. @@ -187,7 +192,11 @@ def owner(self, ip_id: str) -> str: raise e def set_ip_metadata( - self, ip_id: str, metadata_uri: str, metadata_hash: str, tx_options: dict = None + self, + ip_id: str, + metadata_uri: str, + metadata_hash: str, + tx_options: dict | None = None, ) -> dict: """Sets the metadataURI for an IP asset. @@ -219,7 +228,9 @@ def set_ip_metadata( except Exception as e: raise e - def transfer_erc20(self, ip_id: str, tokens: list, tx_options: dict = None) -> dict: + def transfer_erc20( + self, ip_id: str, tokens: list, tx_options: dict | None = None + ) -> dict: """Transfers ERC20 tokens from the IP Account to the target address. :param ip_id str: The IP ID to transfer tokens from. diff --git a/src/story_protocol_python_sdk/resources/IPAsset.py b/src/story_protocol_python_sdk/resources/IPAsset.py index 11eb3ca..11928a6 100644 --- a/src/story_protocol_python_sdk/resources/IPAsset.py +++ b/src/story_protocol_python_sdk/resources/IPAsset.py @@ -77,7 +77,7 @@ def mint( metadata_uri: str, metadata_hash: bytes, allow_duplicates: bool = False, - tx_options: dict = None, + tx_options: dict | None = None, ): spg_nft_client = SPGNFTImplClient(self.web3, contract_address=nft_contract) @@ -110,9 +110,9 @@ def register( self, nft_contract: str, token_id: int, - ip_metadata: dict = None, - deadline: int = None, - tx_options: dict = None, + ip_metadata: dict | None = None, + deadline: int | None = None, + tx_options: dict | None = None, ) -> dict: """ Register an NFT as IP, creating a corresponding IP record. @@ -132,7 +132,7 @@ def register( if self._is_registered(ip_id): return {"tx_hash": None, "ip_id": ip_id} - req_object = { + req_object: dict = { "tokenId": token_id, "nftContract": self.web3.to_checksum_address(nft_contract), "ipMetadata": { @@ -222,8 +222,8 @@ def register_derivative( max_minting_fee: int = 0, max_rts: int = 0, max_revenue_share: int = 0, - license_template: str = None, - tx_options: dict = None, + license_template: str | None = None, + tx_options: dict | None = None, ) -> dict: """ Registers a derivative directly with parent IP's license terms, without needing license tokens, @@ -287,7 +287,7 @@ def register_derivative_with_license_tokens( child_ip_id: str, license_token_ids: list, max_rts: int = 0, - tx_options: dict = None, + tx_options: dict | None = None, ) -> dict: """ Registers a derivative with license tokens. The derivative IP is registered with license tokens @@ -338,10 +338,10 @@ def mint_and_register_ip_asset_with_pil_terms( self, spg_nft_contract: str, terms: list, - ip_metadata: dict = None, - recipient: str = None, + ip_metadata: dict | None = None, + recipient: str | None = None, allow_duplicates: bool = False, - tx_options: dict = None, + tx_options: dict | None = None, ) -> dict: """ Mint an NFT from a collection and register it as an IP. @@ -502,10 +502,10 @@ def mint_and_register_ip_asset_with_pil_terms( def mint_and_register_ip( self, spg_nft_contract: str, - recipient: str = None, - ip_metadata: dict = None, + recipient: str | None = None, + ip_metadata: dict | None = None, allow_duplicates: bool = True, - tx_options: dict = None, + tx_options: dict | None = None, ) -> dict: """ Mint an NFT from a SPGNFT collection and register it with metadata as an IP. @@ -573,9 +573,9 @@ def register_ip_and_attach_pil_terms( nft_contract: str, token_id: int, license_terms_data: dict, - ip_metadata: dict = None, - deadline: int = None, - tx_options: dict = None, + ip_metadata: dict | None = None, + deadline: int | None = None, + tx_options: dict | None = None, ) -> dict: """ Register a given NFT as an IP and attach Programmable IP License Terms. @@ -1030,7 +1030,7 @@ def _is_registered(self, ip_id: str) -> bool: """ return self.ip_asset_registry_client.isRegistered(ip_id) - def _parse_tx_ip_registered_event(self, tx_receipt: dict) -> int: + def _parse_tx_ip_registered_event(self, tx_receipt: dict) -> dict: """ Parse the IPRegistered event from a transaction receipt. @@ -1049,9 +1049,9 @@ def _parse_tx_ip_registered_event(self, tx_receipt: dict) -> int: "ip_id": self.web3.to_checksum_address(ip_id), "token_id": token_id, } - return None + raise ValueError("IPRegistered event not found in transaction receipt.") - def _parse_tx_license_term_attached_event(self, tx_receipt: dict) -> int: + def _parse_tx_license_term_attached_event(self, tx_receipt: dict) -> int | None: """ Parse the LicenseTermsAttached event from a transaction receipt. @@ -1069,7 +1069,7 @@ def _parse_tx_license_term_attached_event(self, tx_receipt: dict) -> int: return license_terms_id return None - def _parse_tx_license_terms_attached_event(self, tx_receipt: dict) -> list: + def _parse_tx_license_terms_attached_event(self, tx_receipt: dict) -> list | None: """ Parse the LicenseTermsAttached events from a transaction receipt. diff --git a/src/story_protocol_python_sdk/resources/License.py b/src/story_protocol_python_sdk/resources/License.py index 2381680..3700c08 100644 --- a/src/story_protocol_python_sdk/resources/License.py +++ b/src/story_protocol_python_sdk/resources/License.py @@ -1,5 +1,6 @@ # src/story_protcol_python_sdk/resources/License.py +from ens.ens import HexStr from web3 import Web3 from story_protocol_python_sdk.abi.IPAssetRegistry.IPAssetRegistry_client import ( @@ -62,7 +63,7 @@ def register_pil_terms( commercial_use: bool, commercial_attribution: bool, commercializer_checker: str, - commercializer_checker_data: str, + commercializer_checker_data: HexStr, commercial_rev_share: int, commercial_rev_ceiling: int, derivatives_allowed: bool, @@ -72,7 +73,7 @@ def register_pil_terms( derivative_rev_ceiling: int, currency: str, uri: str, - tx_options: dict = None, + tx_options: dict | None = None, ) -> dict: """ Registers new license terms and returns the ID of the newly registered license terms. @@ -161,7 +162,9 @@ def register_pil_terms( except Exception as e: raise e - def register_non_com_social_remixing_pil(self, tx_options: dict = None) -> dict: + def register_non_com_social_remixing_pil( + self, tx_options: dict | None = None + ) -> dict: """ Convenient function to register a PIL non-commercial social remix license to the registry. @@ -197,9 +200,9 @@ def register_commercial_use_pil( self, default_minting_fee: int, currency: str, - royalty_policy: str = None, - tx_options: dict = None, - ) -> dict: + royalty_policy: str | None = None, + tx_options: dict | None = None, + ) -> dict | None: """ Convenient function to register a PIL commercial use license to the registry. @@ -248,8 +251,8 @@ def register_commercial_remix_pil( currency: str, commercial_rev_share: int, royalty_policy: str, - tx_options: dict = None, - ) -> dict: + tx_options: dict | None = None, + ) -> dict | None: """ Convenient function to register a PIL commercial remix license to the registry. @@ -294,7 +297,7 @@ def register_commercial_remix_pil( except Exception as e: raise e - def _parse_tx_license_terms_registered_event(self, tx_receipt: dict) -> int: + def _parse_tx_license_terms_registered_event(self, tx_receipt: dict) -> int | None: """ Parse the LicenseTermsRegistered event from a transaction receipt. @@ -316,7 +319,7 @@ def attach_license_terms( ip_id: str, license_template: str, license_terms_id: int, - tx_options: dict = None, + tx_options: dict | None = None, ) -> dict: """ Attaches license terms to an IP. @@ -375,7 +378,7 @@ def mint_license_tokens( receiver: str, max_minting_fee: int = 0, max_revenue_share: int = 0, - tx_options: dict = None, + tx_options: dict | None = None, ) -> dict: """ Mints license tokens for the license terms attached to an IP. @@ -441,7 +444,7 @@ def mint_license_tokens( except Exception as e: raise e - def _parse_tx_license_tokens_minted_event(self, tx_receipt: dict) -> list: + def _parse_tx_license_tokens_minted_event(self, tx_receipt: dict) -> list | None: """ Parse the LicenseTokenMinted event from a transaction receipt. @@ -479,9 +482,9 @@ def predict_minting_license_fee( licensor_ip_id: str, license_terms_id: int, amount: int, - license_template: str = None, - receiver: str = None, - tx_options: dict = None, + license_template: str | None = None, + receiver: str | None = None, + tx_options: dict | None = None, ) -> dict: """ Pre-compute the minting license fee for the given IP and license terms. @@ -505,16 +508,17 @@ def predict_minting_license_fee( if not self.license_template_client.exists(license_terms_id): raise ValueError(f"License terms id {license_terms_id} does not exist.") - # Set defaults if not provided - if not receiver: - receiver = self.account.address - if not license_template: - license_template = self.license_template_client.contract.address - - # Convert addresses to checksum format licensor_ip_id = self.web3.to_checksum_address(licensor_ip_id) - license_template = self.web3.to_checksum_address(license_template) - receiver = self.web3.to_checksum_address(receiver) + license_template = ( + self.web3.to_checksum_address(license_template) + if license_template + else self.license_template_client.contract.address + ) + receiver = ( + self.web3.to_checksum_address(receiver) + if receiver + else self.account.address + ) response = self.licensing_module_client.predictMintingLicenseFee( licensor_ip_id, @@ -535,8 +539,8 @@ def set_licensing_config( ip_id: str, license_terms_id: int, licensing_config: dict, - license_template: str = None, - tx_options: dict = None, + license_template: str | None = None, + tx_options: dict | None = None, ) -> dict: """ Sets the licensing configuration for a specific license terms of an IP. If both licenseTemplate and licenseTermsId are not specified then the licensing config apply to all licenses of given IP. @@ -646,4 +650,3 @@ def set_licensing_config( except Exception as e: raise ValueError(f"Failed to set licensing config: {str(e)}") - raise ValueError(f"Failed to set licensing config: {str(e)}") diff --git a/src/story_protocol_python_sdk/resources/NFTClient.py b/src/story_protocol_python_sdk/resources/NFTClient.py index 41a7217..d6c72cb 100644 --- a/src/story_protocol_python_sdk/resources/NFTClient.py +++ b/src/story_protocol_python_sdk/resources/NFTClient.py @@ -1,5 +1,6 @@ # src/story_protcol_python_sdk/resources/NFTClient.py +from eth_typing.evm import ChecksumAddress from web3 import Web3 from story_protocol_python_sdk.abi.RegistrationWorkflows.RegistrationWorkflows_client import ( @@ -35,11 +36,11 @@ def create_nft_collection( mint_fee_recipient: str, contract_uri: str, base_uri: str = "", - max_supply: int = None, - mint_fee: int = None, - mint_fee_token: str = None, - owner: str = None, - tx_options: dict = None, + max_supply: int | None = None, + mint_fee: int | None = None, + mint_fee_token: str | None = None, + owner: str | None = None, + tx_options: dict | None = None, ) -> dict: """ Creates a new SPG NFT Collection. @@ -99,7 +100,9 @@ def create_nft_collection( except Exception as e: raise e - def _parse_tx_collection_created_event(self, tx_receipt: dict) -> int: + def _parse_tx_collection_created_event( + self, tx_receipt: dict + ) -> ChecksumAddress | None: """ Parse the CollectionCreated event from a transaction receipt. diff --git a/src/story_protocol_python_sdk/resources/Permission.py b/src/story_protocol_python_sdk/resources/Permission.py index 3bcc992..845cdc9 100644 --- a/src/story_protocol_python_sdk/resources/Permission.py +++ b/src/story_protocol_python_sdk/resources/Permission.py @@ -44,7 +44,7 @@ def set_permission( to: str, permission: int, func: str = DEFAULT_FUNCTION_SELECTOR, - tx_options: dict = None, + tx_options: dict | None = None, ) -> dict: """ Sets the permission for a specific function call. @@ -92,7 +92,7 @@ def set_permission( raise Exception(f"Failed to set permission for IP {ip_id}: {str(e)}") def set_all_permissions( - self, ip_id: str, signer: str, permission: int, tx_options: dict = None + self, ip_id: str, signer: str, permission: int, tx_options: dict | None = None ) -> dict: """ Sets permission to a signer for all functions across all modules. @@ -139,8 +139,8 @@ def create_set_permission_signature( to: str, permission: int, func: str = DEFAULT_FUNCTION_SELECTOR, - deadline: int = None, - tx_options: dict = None, + deadline: int | None = None, + tx_options: dict | None = None, ) -> dict: """ Specific permission overrides wildcard permission with signature. @@ -180,7 +180,6 @@ def create_set_permission_signature( # Get state and calculate deadline state = ip_account_client.state() - self.web3.eth.get_block("latest").timestamp calculated_deadline = self.sign_util.get_deadline(deadline) # Get permission signature diff --git a/src/story_protocol_python_sdk/resources/Royalty.py b/src/story_protocol_python_sdk/resources/Royalty.py index 100965f..8e86506 100644 --- a/src/story_protocol_python_sdk/resources/Royalty.py +++ b/src/story_protocol_python_sdk/resources/Royalty.py @@ -95,7 +95,7 @@ def pay_royalty_on_behalf( payer_ip_id: str, token: str, amount: int, - tx_options: dict = None, + tx_options: dict | None = None, ) -> dict: """ Allows the function caller to pay royalties to the receiver IP asset on behalf of the payer IP asset. @@ -147,8 +147,8 @@ def claim_all_revenue( child_ip_ids: list, royalty_policies: list, currency_tokens: list, - claim_options: dict = None, - tx_options: dict = None, + claim_options: dict | None = None, + tx_options: dict | None = None, ) -> dict: """ Claims all revenue from the child IPs of an ancestor IP, then optionally transfers and unwraps tokens. @@ -231,7 +231,7 @@ def transfer_to_vault( ancestor_ip_id: str, token: str, royalty_policy: str = "LAP", - tx_options: dict = None, + tx_options: dict | None = None, ) -> dict: """ Transfers to vault an amount of revenue tokens claimable via a royalty policy. @@ -246,7 +246,9 @@ def transfer_to_vault( try: if not self.web3.is_address(token): raise ValueError(f'Token address "{token}" is invalid.') - + royalty_policy_client: ( + RoyaltyPolicyLAPClient | RoyaltyPolicyLRPClient | None + ) = None # Determine which royalty policy to use if royalty_policy == "LAP": royalty_policy_client = self.royalty_policy_lap_client diff --git a/src/story_protocol_python_sdk/resources/WIP.py b/src/story_protocol_python_sdk/resources/WIP.py index f6d627b..37d7c2f 100644 --- a/src/story_protocol_python_sdk/resources/WIP.py +++ b/src/story_protocol_python_sdk/resources/WIP.py @@ -22,7 +22,7 @@ def __init__(self, web3: Web3, account, chain_id: int): self.wip_client = WIPClient(web3) - def deposit(self, amount: int, tx_options: dict = None) -> dict: + def deposit(self, amount: int, tx_options: dict | None = None) -> dict: """ Wraps the selected amount of IP to WIP. The WIP will be deposited to the wallet that transferred the IP. @@ -57,7 +57,7 @@ def deposit(self, amount: int, tx_options: dict = None) -> dict: except Exception as e: raise ValueError(f"Failed to deposit IP for WIP: {str(e)}") - def withdraw(self, amount: int, tx_options: dict = None) -> dict: + def withdraw(self, amount: int, tx_options: dict | None = None) -> dict: """ Unwraps the selected amount of WIP to IP. @@ -82,7 +82,9 @@ def withdraw(self, amount: int, tx_options: dict = None) -> dict: except Exception as e: raise ValueError(f"Failed to withdraw WIP: {str(e)}") - def approve(self, spender: str, amount: int, tx_options: dict = None) -> dict: + def approve( + self, spender: str, amount: int, tx_options: dict | None = None + ) -> dict: """ Approve a spender to use the wallet's WIP balance. @@ -131,7 +133,7 @@ def balance_of(self, address: str) -> int: except Exception as e: raise ValueError(f"Failed to get WIP balance: {str(e)}") - def transfer(self, to: str, amount: int, tx_options: dict = None) -> dict: + def transfer(self, to: str, amount: int, tx_options: dict | None = None) -> dict: """ Transfers `amount` of WIP to a recipient `to`. @@ -164,7 +166,7 @@ def transfer(self, to: str, amount: int, tx_options: dict = None) -> dict: raise ValueError(f"Failed to transfer WIP: {str(e)}") def transfer_from( - self, from_address: str, to: str, amount: int, tx_options: dict = None + self, from_address: str, to: str, amount: int, tx_options: dict | None = None ) -> dict: """ Transfers `amount` of WIP from `from_address` to a recipient `to`. diff --git a/src/story_protocol_python_sdk/scripts/config.json b/src/story_protocol_python_sdk/scripts/config.json index ed90911..8f580e4 100644 --- a/src/story_protocol_python_sdk/scripts/config.json +++ b/src/story_protocol_python_sdk/scripts/config.json @@ -1,258 +1,236 @@ { - "contracts": [ - { - "contract_name": "AccessController", - "contract_address": "0xcCF37d0a503Ee1D4C11208672e622ed3DFB2275a", - "functions": [ - "PermissionSet", - "setPermission", - "setAllPermissions", - "setBatchPermissions", - "setTransientPermission", - "setTransientBatchPermissions" - ] - }, - { - "contract_name": "DisputeModule", - "contract_address": "0x9b7A9c70AFF961C799110954fc06F3093aeb94C5", - "functions": [ - "DisputeCancelled", - "DisputeRaised", - "DisputeResolved", - "cancelDispute", - "raiseDispute", - "resolveDispute", - "isWhitelistedDisputeTag" - ] - }, - { - "contract_name": "IPAccountImpl", - "contract_address": "0xc93d49fEdED1A2fbE3B54223Df65f4edB3845eb0", - "functions": [ - "execute", - "executeBatch", - "executeWithSig", - "state", - "token", - "owner" - ] - }, - { - "contract_name": "IPAssetRegistry", - "contract_address": "0x77319B4031e6eF1250907aa00018B8B1c67a244b", - "functions": [ - "IPRegistered", - "ipId", - "isRegistered", - "register", - "IPAccountRegistered" - ] - }, - { - "contract_name": "IpRoyaltyVaultImpl", - "contract_address": "0x63cC7611316880213f3A4Ba9bD72b0EaA2010298", - "functions": [ - "claimableRevenue", - "ipId", - "RoyaltyTokensCollected", - "RevenueTokenClaimed", - "balanceOf" - ] - }, - { - "contract_name": "PILicenseTemplate", - "contract_address": "0x2E896b0b2Fdb7457499B56AAaA4AE55BCB4Cd316", - "functions": [ - "getLicenseTermsId", - "registerLicenseTerms", - "LicenseTermsRegistered", - "getLicenseTerms", - "exists" - ] - }, - { - "contract_name": "LicensingModule", - "contract_address": "0x04fbd8a2e56dd85CFD5500A4A4DfA955B9f1dE6f", - "functions": [ - "attachLicenseTerms", - "mintLicenseTokens", - "LicenseTokensMinted", - "registerDerivativeWithLicenseTokens", - "registerDerivative", - "getLicenseTerms", - "LicenseTermsAttached", - "predictMintingLicenseFee", - "setLicensingConfig" - ] - }, - { - "contract_name": "ModuleRegistry", - "contract_address": "0x022DBAAeA5D8fB31a0Ad793335e39Ced5D631fa5", - "functions": [ - "isRegistered", - "getDefaultLicenseTerms" - ] - }, - { - "contract_name": "RoyaltyModule", - "contract_address": "0xD2f60c40fEbccf6311f8B47c4f2Ec6b040400086", - "functions": [ - "payRoyaltyOnBehalf", - "isWhitelistedRoyaltyPolicy", - "isWhitelistedRoyaltyToken", - "ipRoyaltyVaults", - "IpRoyaltyVaultDeployed" - ] - }, - { - "contract_name": "RoyaltyPolicyLAP", - "contract_address": "0xBe54FB168b3c982b7AaE60dB6CF75Bd8447b390E", - "functions": [ - "onRoyaltyPayment", - "getRoyaltyData", - "transferToVault" - ] - }, - { - "contract_name": "LicenseToken", - "contract_address": "0xFe3838BFb30B34170F00030B52eA4893d8aAC6bC", - "functions": [ - "ownerOf" - ] - }, - { - "contract_name": "GroupingWorkflows", - "contract_address": "0xD7c0beb3aa4DCD4723465f1ecAd045676c24CDCd", - "functions": [ - "mintAndRegisterIpAndAttachLicenseAndAddToGroup", - "registerIpAndAttachLicenseAndAddToGroup", - "registerGroupAndAttachLicense", - "registerGroupAndAttachLicenseAndAddIps", - "collectRoyaltiesAndClaimReward", - "CollectedRoyaltiesToGroupPool", - "RoyaltyPaid" - ] - }, - { - "contract_name": "RegistrationWorkflows", - "contract_address": "0xbe39E1C756e921BD25DF86e7AAa31106d1eb0424", - "functions": [ - "createCollection", - "mintAndRegisterIp", - "registerIp", - "CollectionCreated", - "multicall" - ] - }, - { - "contract_name": "LicenseAttachmentWorkflows", - "contract_address": "0xcC2E862bCee5B6036Db0de6E06Ae87e524a79fd8", - "functions": [ - "registerPILTermsAndAttach", - "registerIpAndAttachPILTerms", - "mintAndRegisterIpAndAttachPILTerms", - "multicall" - ] - }, - { - "contract_name": "RoyaltyWorkflows", - "contract_address": "0x9515faE61E0c0447C6AC6dEe5628A2097aFE1890", - "functions": [ - "transferToVaultAndSnapshotAndClaimByTokenBatch", - "transferToVaultAndSnapshotAndClaimBySnapshotBatch", - "snapshotAndClaimByTokenBatch", - "snapshotAndClaimBySnapshotBatch", - "claimAllRevenue" - ] - }, - { - "contract_name": "RoyaltyTokenDistributionWorkflows", - "contract_address": "0xa38f42B8d33809917f23997B8423054aAB97322C", - "functions": [ - "mintAndRegisterIpAndAttachPILTermsAndDistributeRoyaltyTokens", - "mintAndRegisterIpAndMakeDerivativeAndDistributeRoyaltyTokens", - "registerIpAndAttachPILTermsAndDeployRoyaltyVault", - "distributeRoyaltyTokens", - "registerIpAndMakeDerivativeAndDeployRoyaltyVault" - ] - }, - { - "contract_name": "CoreMetadataModule", - "contract_address": "0x6E81a25C99C6e8430aeC7353325EB138aFE5DC16", - "functions": [] - }, - { - "contract_name": "CoreMetadataViewModule", - "contract_address": "0xB3F88038A983CeA5753E11D144228Ebb5eACdE20", - "functions": [] - }, - { - "contract_name": "GroupingModule", - "contract_address": "0x69D3a7aa9edb72Bc226E745A7cCdd50D947b69Ac", - "functions": [ - "registerGroup", - "addIp", - "IPGroupRegistered" - ] - }, - { - "contract_name": "LicenseRegistry", - "contract_address": "0x529a750E02d8E2f15649c13D69a465286a780e24", - "functions": [ - "exists", - "hasIpAttachedLicenseTerms", - "getRoyaltyPercent" - ] - }, - { - "contract_name": "RoyaltyPolicyLRP", - "contract_address": "0x9156e603C949481883B1d3355c6f1132D191fC41", - "functions": ["transferToVault"] - }, - { - "contract_name": "ArbitrationPolicyUMA", - "contract_address": "0xfFD98c3877B8789124f02C7E8239A4b0Ef11E936", - "functions": [ - "minLiveness", - "maxLiveness", - "maxBonds", - "disputeIdToAssertionId", - "oov3" - ] - }, - { - "contract_name": "MockERC20", - "contract_address": "0xF2104833d386a2734a4eB3B8ad6FC6812F29E38E", - "functions": [ - "transfer", - "balanceOf" - ] - }, - { - "contract_name": "WIP", - "contract_address": "0x1514000000000000000000000000000000000000", - "functions": [ - "deposit", - "withdraw", - "approve", - "balanceOf", - "transfer", - "transferFrom", - "allowance" - ] - }, - { - "contract_name": "SPGNFTImpl", - "contract_address": "0xc09e3788Fdfbd3dd8CDaa2aa481B52CcFAb74a42", - "functions": [ - "mintFeeToken", - "mintFee" - ] - }, - { - "contract_name": "DerivativeWorkflows", - "contract_address": "0x9e2d496f72C547C2C535B167e06ED8729B374a4f", - "functions": [] - } - ] + "contracts": [ + { + "contract_name": "AccessController", + "contract_address": "0xcCF37d0a503Ee1D4C11208672e622ed3DFB2275a", + "functions": [ + "PermissionSet", + "setPermission", + "setAllPermissions", + "setBatchPermissions", + "setTransientPermission", + "setTransientBatchPermissions" + ] + }, + { + "contract_name": "DisputeModule", + "contract_address": "0x9b7A9c70AFF961C799110954fc06F3093aeb94C5", + "functions": [ + "DisputeCancelled", + "DisputeRaised", + "DisputeResolved", + "cancelDispute", + "raiseDispute", + "resolveDispute", + "isWhitelistedDisputeTag", + "tagIfRelatedIpInfringed" + ] + }, + { + "contract_name": "IPAccountImpl", + "contract_address": "0xc93d49fEdED1A2fbE3B54223Df65f4edB3845eb0", + "functions": [ + "execute", + "executeBatch", + "executeWithSig", + "state", + "token", + "owner" + ] + }, + { + "contract_name": "IPAssetRegistry", + "contract_address": "0x77319B4031e6eF1250907aa00018B8B1c67a244b", + "functions": [ + "IPRegistered", + "ipId", + "isRegistered", + "register", + "IPAccountRegistered" + ] + }, + { + "contract_name": "IpRoyaltyVaultImpl", + "contract_address": "0x63cC7611316880213f3A4Ba9bD72b0EaA2010298", + "functions": [ + "claimableRevenue", + "ipId", + "RoyaltyTokensCollected", + "RevenueTokenClaimed", + "balanceOf" + ] + }, + { + "contract_name": "PILicenseTemplate", + "contract_address": "0x2E896b0b2Fdb7457499B56AAaA4AE55BCB4Cd316", + "functions": [ + "getLicenseTermsId", + "registerLicenseTerms", + "LicenseTermsRegistered", + "getLicenseTerms", + "exists" + ] + }, + { + "contract_name": "LicensingModule", + "contract_address": "0x04fbd8a2e56dd85CFD5500A4A4DfA955B9f1dE6f", + "functions": [ + "attachLicenseTerms", + "mintLicenseTokens", + "LicenseTokensMinted", + "registerDerivativeWithLicenseTokens", + "registerDerivative", + "getLicenseTerms", + "LicenseTermsAttached", + "predictMintingLicenseFee", + "setLicensingConfig" + ] + }, + { + "contract_name": "ModuleRegistry", + "contract_address": "0x022DBAAeA5D8fB31a0Ad793335e39Ced5D631fa5", + "functions": ["isRegistered", "getDefaultLicenseTerms"] + }, + { + "contract_name": "RoyaltyModule", + "contract_address": "0xD2f60c40fEbccf6311f8B47c4f2Ec6b040400086", + "functions": [ + "payRoyaltyOnBehalf", + "isWhitelistedRoyaltyPolicy", + "isWhitelistedRoyaltyToken", + "ipRoyaltyVaults", + "IpRoyaltyVaultDeployed" + ] + }, + { + "contract_name": "RoyaltyPolicyLAP", + "contract_address": "0xBe54FB168b3c982b7AaE60dB6CF75Bd8447b390E", + "functions": ["onRoyaltyPayment", "getRoyaltyData", "transferToVault"] + }, + { + "contract_name": "LicenseToken", + "contract_address": "0xFe3838BFb30B34170F00030B52eA4893d8aAC6bC", + "functions": ["ownerOf"] + }, + { + "contract_name": "GroupingWorkflows", + "contract_address": "0xD7c0beb3aa4DCD4723465f1ecAd045676c24CDCd", + "functions": [ + "mintAndRegisterIpAndAttachLicenseAndAddToGroup", + "registerIpAndAttachLicenseAndAddToGroup", + "registerGroupAndAttachLicense", + "registerGroupAndAttachLicenseAndAddIps", + "collectRoyaltiesAndClaimReward", + "CollectedRoyaltiesToGroupPool", + "RoyaltyPaid" + ] + }, + { + "contract_name": "RegistrationWorkflows", + "contract_address": "0xbe39E1C756e921BD25DF86e7AAa31106d1eb0424", + "functions": [ + "createCollection", + "mintAndRegisterIp", + "registerIp", + "CollectionCreated", + "multicall" + ] + }, + { + "contract_name": "LicenseAttachmentWorkflows", + "contract_address": "0xcC2E862bCee5B6036Db0de6E06Ae87e524a79fd8", + "functions": [ + "registerPILTermsAndAttach", + "registerIpAndAttachPILTerms", + "mintAndRegisterIpAndAttachPILTerms", + "multicall" + ] + }, + { + "contract_name": "RoyaltyWorkflows", + "contract_address": "0x9515faE61E0c0447C6AC6dEe5628A2097aFE1890", + "functions": [ + "transferToVaultAndSnapshotAndClaimByTokenBatch", + "transferToVaultAndSnapshotAndClaimBySnapshotBatch", + "snapshotAndClaimByTokenBatch", + "snapshotAndClaimBySnapshotBatch", + "claimAllRevenue" + ] + }, + { + "contract_name": "RoyaltyTokenDistributionWorkflows", + "contract_address": "0xa38f42B8d33809917f23997B8423054aAB97322C", + "functions": [ + "mintAndRegisterIpAndAttachPILTermsAndDistributeRoyaltyTokens", + "mintAndRegisterIpAndMakeDerivativeAndDistributeRoyaltyTokens", + "registerIpAndAttachPILTermsAndDeployRoyaltyVault", + "distributeRoyaltyTokens", + "registerIpAndMakeDerivativeAndDeployRoyaltyVault" + ] + }, + { + "contract_name": "CoreMetadataModule", + "contract_address": "0x6E81a25C99C6e8430aeC7353325EB138aFE5DC16", + "functions": [] + }, + { + "contract_name": "CoreMetadataViewModule", + "contract_address": "0xB3F88038A983CeA5753E11D144228Ebb5eACdE20", + "functions": [] + }, + { + "contract_name": "GroupingModule", + "contract_address": "0x69D3a7aa9edb72Bc226E745A7cCdd50D947b69Ac", + "functions": ["registerGroup", "addIp", "IPGroupRegistered"] + }, + { + "contract_name": "LicenseRegistry", + "contract_address": "0x529a750E02d8E2f15649c13D69a465286a780e24", + "functions": ["exists", "hasIpAttachedLicenseTerms", "getRoyaltyPercent"] + }, + { + "contract_name": "RoyaltyPolicyLRP", + "contract_address": "0x9156e603C949481883B1d3355c6f1132D191fC41", + "functions": ["transferToVault"] + }, + { + "contract_name": "ArbitrationPolicyUMA", + "contract_address": "0xfFD98c3877B8789124f02C7E8239A4b0Ef11E936", + "functions": [ + "minLiveness", + "maxLiveness", + "maxBonds", + "disputeIdToAssertionId", + "oov3" + ] + }, + { + "contract_name": "MockERC20", + "contract_address": "0xF2104833d386a2734a4eB3B8ad6FC6812F29E38E", + "functions": ["transfer", "balanceOf"] + }, + { + "contract_name": "WIP", + "contract_address": "0x1514000000000000000000000000000000000000", + "functions": [ + "deposit", + "withdraw", + "approve", + "balanceOf", + "transfer", + "transferFrom", + "allowance" + ] + }, + { + "contract_name": "SPGNFTImpl", + "contract_address": "0xc09e3788Fdfbd3dd8CDaa2aa481B52CcFAb74a42", + "functions": ["mintFeeToken", "mintFee"] + }, + { + "contract_name": "DerivativeWorkflows", + "contract_address": "0x9e2d496f72C547C2C535B167e06ED8729B374a4f", + "functions": [] + } + ] } diff --git a/src/story_protocol_python_sdk/story_client.py b/src/story_protocol_python_sdk/story_client.py index 652ce1f..51ea6b5 100644 --- a/src/story_protocol_python_sdk/story_client.py +++ b/src/story_protocol_python_sdk/story_client.py @@ -48,15 +48,15 @@ def __init__(self, web3, account, chain_id: int): self.account = account self.chain_id = chain_id - self._ip_asset = None - self._license = None - self._royalty = None - self._ip_account = None - self._permission = None - self._nft_client = None - self._dispute = None - self._wip = None - self._group = None + self._ip_asset: IPAsset | None = None + self._license: License | None = None + self._royalty: Royalty | None = None + self._ip_account: IPAccount | None = None + self._permission: Permission | None = None + self._nft_client: NFTClient | None = None + self._dispute: Dispute | None = None + self._wip: WIP | None = None + self._group: Group | None = None @property def IPAsset(self) -> IPAsset: diff --git a/src/story_protocol_python_sdk/utils/constants.py b/src/story_protocol_python_sdk/utils/constants.py index 8d17752..e16eb8d 100644 --- a/src/story_protocol_python_sdk/utils/constants.py +++ b/src/story_protocol_python_sdk/utils/constants.py @@ -1,5 +1,9 @@ +from eth_typing import HexStr + ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" -ZERO_HASH = "0x0000000000000000000000000000000000000000000000000000000000000000" +ZERO_HASH: HexStr = HexStr( + "0x0000000000000000000000000000000000000000000000000000000000000000" +) ROYALTY_POLICY = "0xBe54FB168b3c982b7AaE60dB6CF75Bd8447b390E" ZERO_FUNC = "0x00000000" DEFAULT_FUNCTION_SELECTOR = "0x00000000" diff --git a/src/story_protocol_python_sdk/utils/license_terms.py b/src/story_protocol_python_sdk/utils/license_terms.py index 5597e55..ad05e43 100644 --- a/src/story_protocol_python_sdk/utils/license_terms.py +++ b/src/story_protocol_python_sdk/utils/license_terms.py @@ -1,5 +1,6 @@ # src/story_protocol_python_sdk/utils/license_terms.py +from ens.async_ens import HexStr from web3 import Web3 from story_protocol_python_sdk.abi.RoyaltyModule.RoyaltyModule_client import ( @@ -134,7 +135,7 @@ def validate_license_terms(self, params): commercializer_checker_data = params.get( "commercializer_checker_data", ZERO_ADDRESS ) - if isinstance(commercializer_checker_data, str): + if isinstance(commercializer_checker_data, HexStr): params["commercializer_checker_data"] = Web3.to_bytes( hexstr=commercializer_checker_data ) diff --git a/src/story_protocol_python_sdk/utils/oov3.py b/src/story_protocol_python_sdk/utils/oov3.py index ee5b3b7..81dae77 100644 --- a/src/story_protocol_python_sdk/utils/oov3.py +++ b/src/story_protocol_python_sdk/utils/oov3.py @@ -40,7 +40,9 @@ def get_assertion_bond( :return int: The bond amount. """ try: - oov3_contract_address = get_oov3_contract(arbitration_policy_uma_client) + oov3_contract_address = Web3.to_checksum_address( + get_oov3_contract(arbitration_policy_uma_client) + ) oov3_contract = web3.eth.contract( address=oov3_contract_address, abi=ASSERTION_ABI diff --git a/src/story_protocol_python_sdk/utils/sign.py b/src/story_protocol_python_sdk/utils/sign.py index 0fe266c..2e63bd6 100644 --- a/src/story_protocol_python_sdk/utils/sign.py +++ b/src/story_protocol_python_sdk/utils/sign.py @@ -26,7 +26,7 @@ def __init__(self, web3: Web3, chain_id: int, account): def get_signature( self, - state: str, + state: bytes, to: str, encode_data: bytes, verifying_contract: str, @@ -98,7 +98,7 @@ def get_signature( except Exception as e: raise e - def get_deadline(self, deadline: int = None) -> int: + def get_deadline(self, deadline: int | None = None) -> int: """ Calculate the deadline for a transaction. @@ -119,8 +119,8 @@ def get_permission_signature( ip_id: str, deadline: int, permissions: list, - permission_func: str = None, - state: str = None, + state: bytes, + permission_func: str | None = None, ) -> dict: """ Get the signature for setting permissions. diff --git a/src/story_protocol_python_sdk/utils/transaction_utils.py b/src/story_protocol_python_sdk/utils/transaction_utils.py index 8f58ef3..3c14c6a 100644 --- a/src/story_protocol_python_sdk/utils/transaction_utils.py +++ b/src/story_protocol_python_sdk/utils/transaction_utils.py @@ -6,7 +6,11 @@ def build_and_send_transaction( - web3: Web3, account, client_function, *client_args, tx_options: dict = None + web3: Web3, + account, + client_function, + *client_args, + tx_options: dict | None = None, ) -> dict: """ Builds and sends a transaction using the provided client function and arguments. diff --git a/tests/demo/demo.py b/tests/demo/demo.py index e126c1c..38a6b55 100644 --- a/tests/demo/demo.py +++ b/tests/demo/demo.py @@ -1,6 +1,11 @@ import os -from demo_utils import ( +from dotenv import load_dotenv +from web3 import Web3 + +from story_protocol_python_sdk import StoryClient + +from .demo_utils import ( PIL_LICENSE_TEMPLATE, ROYALTY_POLICY, MockERC20, @@ -8,10 +13,6 @@ get_token_id, mint_tokens, ) -from dotenv import load_dotenv -from web3 import Web3 - -from story_protocol_python_sdk import StoryClient def main(): @@ -42,14 +43,18 @@ def main(): registered_ip_asset_response = story_client.IPAsset.register( nft_contract=MockERC721, token_id=token_id ) + if registered_ip_asset_response is None: + raise ValueError("Failed to register IP asset") print( f"Root IPA created at transaction hash {registered_ip_asset_response['txHash']}, IPA ID: {registered_ip_asset_response['ipId']}" ) # 3. Register PIL Terms - register_pil_terms_response = story_client.License.registerCommercialUsePIL( + register_pil_terms_response = story_client.License.register_commercial_use_pil( default_minting_fee=1, currency=MockERC20, royalty_policy=ROYALTY_POLICY ) + if register_pil_terms_response is None: + raise ValueError("Failed to register PIL terms") if "txHash" in register_pil_terms_response: print( f"PIL Terms registered at transaction hash {register_pil_terms_response['txHash']}, License Terms ID: {register_pil_terms_response['licenseTermsId']}" @@ -61,11 +66,13 @@ def main(): # 4. Attach License Terms to IP try: - attach_license_terms_response = story_client.License.attachLicenseTerms( + attach_license_terms_response = story_client.License.attach_license_terms( ip_id=registered_ip_asset_response["ipId"], license_template=PIL_LICENSE_TEMPLATE, license_terms_id=register_pil_terms_response["licenseTermsId"], ) + if attach_license_terms_response is None: + raise ValueError("Failed to attach license terms") print( f"Attached License Terms to IP at transaction hash {attach_license_terms_response['txHash']}" ) @@ -78,7 +85,7 @@ def main(): mint_tokens(MockERC20, web3, account, account.address, 10000) # 5. Mint License - mint_license_response = story_client.License.mintLicenseTokens( + mint_license_response = story_client.License.mint_license_tokens( licensor_ip_id=registered_ip_asset_response["ipId"], license_template=PIL_LICENSE_TEMPLATE, license_terms_id=register_pil_terms_response["licenseTermsId"], @@ -87,6 +94,8 @@ def main(): max_minting_fee=1, max_revenue_share=0, ) + if mint_license_response is None: + raise ValueError("Failed to mint license tokens") print( f"License Token minted at transaction hash {mint_license_response['txHash']}, License Token IDs: {mint_license_response['licenseTokenIds']}" ) @@ -98,15 +107,21 @@ def main(): registered_ip_asset_derivative_response = story_client.IPAsset.register( nft_contract=MockERC721, token_id=derivative_token_id ) + if registered_ip_asset_derivative_response is None: + raise ValueError("Failed to register derivative IP asset") print( f"Derivative IPA created at transaction hash {registered_ip_asset_derivative_response['txHash']}, IPA ID: {registered_ip_asset_derivative_response['ipId']}" ) - link_derivative_response = story_client.IPAsset.registerDerivativeWithLicenseTokens( - child_ip_id=registered_ip_asset_derivative_response["ipId"], - license_token_ids=mint_license_response["licenseTokenIds"], - max_rts=5 * 10**6, + link_derivative_response = ( + story_client.IPAsset.register_derivative_with_license_tokens( + child_ip_id=registered_ip_asset_derivative_response["ipId"], + license_token_ids=mint_license_response["licenseTokenIds"], + max_rts=5 * 10**6, + ) ) + if link_derivative_response is None: + raise ValueError("Failed to link derivative IP asset") print( f"Derivative IPA linked to parent at transaction hash {link_derivative_response['txHash']}" ) diff --git a/tests/integration/test_integration_ip_account.py b/tests/integration/test_integration_ip_account.py index 4dca5c9..6f6f879 100644 --- a/tests/integration/test_integration_ip_account.py +++ b/tests/integration/test_integration_ip_account.py @@ -4,7 +4,11 @@ from eth_abi.abi import encode from eth_account import Account from eth_account.messages import encode_typed_data -from setup_for_integration import ( +from web3 import Web3 + +from story_protocol_python_sdk.story_client import StoryClient + +from .setup_for_integration import ( MockERC20, MockERC721, account, @@ -14,9 +18,6 @@ private_key, web3, ) -from web3 import Web3 - -from story_protocol_python_sdk.story_client import StoryClient class TestBasicIPAccountOperations: diff --git a/tests/integration/test_integration_ip_asset.py b/tests/integration/test_integration_ip_asset.py index ff9a5a0..462c555 100644 --- a/tests/integration/test_integration_ip_asset.py +++ b/tests/integration/test_integration_ip_asset.py @@ -357,8 +357,8 @@ def test_register_ip_and_attach_pil_terms( nft_contract=nft_collection, token_id=token_id, deadline=1000, - license_terms_data=[ - { + license_terms_data={ + 0: { "terms": { "transferable": True, "royalty_policy": ZERO_ADDRESS, @@ -389,7 +389,7 @@ def test_register_ip_and_attach_pil_terms( "expect_group_reward_pool": ZERO_ADDRESS, }, }, - { + 1: { "terms": { "transferable": True, "royalty_policy": ROYALTY_POLICY, @@ -420,7 +420,7 @@ def test_register_ip_and_attach_pil_terms( "expect_group_reward_pool": ZERO_ADDRESS, }, }, - ], + }, ) assert isinstance(result["tx_hash"], str) and result["tx_hash"] diff --git a/tests/integration/test_integration_license.py b/tests/integration/test_integration_license.py index bcc5be9..f0cdc2a 100644 --- a/tests/integration/test_integration_license.py +++ b/tests/integration/test_integration_license.py @@ -302,6 +302,8 @@ def setup_license_terms(story_client: StoryClient, ip_id): commercial_rev_share=100, royalty_policy=ROYALTY_POLICY, ) + if response is None: + raise ValueError("Failed to register license terms") license_id = response["license_terms_id"] # Attach the license terms diff --git a/tests/integration/test_integration_nft_client.py b/tests/integration/test_integration_nft_client.py index e68b1c0..00e56a3 100644 --- a/tests/integration/test_integration_nft_client.py +++ b/tests/integration/test_integration_nft_client.py @@ -148,69 +148,6 @@ def test_invalid_mint_fee_values(self, story_client: StoryClient): or "invalid" in str(e).lower() ) - def test_parameter_omission(self, story_client: StoryClient): - """Test omitting required parameters""" - - with pytest.raises(TypeError): - story_client.NFTClient.create_nft_collection( - # name is omitted - symbol="TEST", - is_public_minting=True, - mint_open=True, - contract_uri="test-uri", - mint_fee_recipient=story_client.account.address, - ) - - with pytest.raises(TypeError): - story_client.NFTClient.create_nft_collection( - name="test-collection", - # symbol is omitted - is_public_minting=True, - mint_open=True, - contract_uri="test-uri", - mint_fee_recipient=story_client.account.address, - ) - - with pytest.raises(TypeError): - story_client.NFTClient.create_nft_collection( - name="test-collection", - symbol="TEST", - # is_public_minting is omitted - mint_open=True, - contract_uri="test-uri", - mint_fee_recipient=story_client.account.address, - ) - - with pytest.raises(TypeError): - story_client.NFTClient.create_nft_collection( - name="test-collection", - symbol="TEST", - is_public_minting=True, - # mint_open is omitted - contract_uri="test-uri", - mint_fee_recipient=story_client.account.address, - ) - - with pytest.raises(TypeError): - story_client.NFTClient.create_nft_collection( - name="test-collection", - symbol="TEST", - is_public_minting=True, - mint_open=True, - # contract_uri is omitted - mint_fee_recipient=story_client.account.address, - ) - - with pytest.raises(TypeError): - story_client.NFTClient.create_nft_collection( - name="test-collection", - symbol="TEST", - is_public_minting=True, - mint_open=True, - contract_uri="test-uri", - # mint_fee_recipient is omitted - ) - def test_authorization_errors(self, story_client: StoryClient): """Test unauthorized operations""" diff --git a/tests/integration/test_integration_royalty.py b/tests/integration/test_integration_royalty.py index 262f8ec..7d9c1ca 100644 --- a/tests/integration/test_integration_royalty.py +++ b/tests/integration/test_integration_royalty.py @@ -49,6 +49,8 @@ def setup_ips_and_licenses(self, story_client: StoryClient): commercial_rev_share=10, royalty_policy=ROYALTY_POLICY, ) + if license_terms_response is None: + raise ValueError("Failed to register license terms") license_terms_id = license_terms_response["license_terms_id"] story_client.License.attach_license_terms( diff --git a/tests/integration/test_integration_wip.py b/tests/integration/test_integration_wip.py index b6d12b8..f059b44 100644 --- a/tests/integration/test_integration_wip.py +++ b/tests/integration/test_integration_wip.py @@ -1,7 +1,17 @@ +from eth_typing import Hash32 + from story_protocol_python_sdk.story_client import StoryClient from .setup_for_integration import wallet_address, wallet_address_2, web3 +# Type assertions to ensure wallet addresses are strings +assert wallet_address is not None, "wallet_address is required" +assert wallet_address_2 is not None, "wallet_address_2 is required" + +# Type cast to satisfy mypy +wallet_address_str: str = wallet_address +wallet_address_2_str: str = wallet_address_2 + class TestWIPDeposit: def test_deposit(self, story_client: StoryClient): @@ -10,7 +20,7 @@ def test_deposit(self, story_client: StoryClient): # Get balances before deposit balance_before = story_client.get_wallet_balance() - wip_before = story_client.WIP.balance_of(wallet_address) + wip_before = story_client.WIP.balance_of(wallet_address_str) # Deposit IP to WIP response = story_client.WIP.deposit(amount=ip_amt) @@ -20,14 +30,14 @@ def test_deposit(self, story_client: StoryClient): # Get balances after deposit balance_after = story_client.get_wallet_balance() - wip_after = story_client.WIP.balance_of(wallet_address) + wip_after = story_client.WIP.balance_of(wallet_address_str) # Verify WIP balance increased by deposit amount assert wip_after == wip_before + ip_amt # Calculate gas cost tx_receipt = web3.eth.wait_for_transaction_receipt( - response["tx_hash"], timeout=300 + Hash32(bytes.fromhex(response["tx_hash"][2:])), timeout=300 ) gas_cost = tx_receipt["gasUsed"] * tx_receipt["effectiveGasPrice"] @@ -41,12 +51,12 @@ def test_transfer(self, story_client: StoryClient): transfer_amount = web3.to_wei("0.01", "ether") # Get balances before transfer - sender_wip_before = story_client.WIP.balance_of(wallet_address) - receiver_wip_before = story_client.WIP.balance_of(wallet_address_2) + sender_wip_before = story_client.WIP.balance_of(wallet_address_str) + receiver_wip_before = story_client.WIP.balance_of(wallet_address_2_str) # Transfer WIP to wallet_address_2 response = story_client.WIP.transfer( - to=wallet_address_2, + to=wallet_address_2_str, amount=transfer_amount, tx_options={"waitForTransaction": True}, ) @@ -55,8 +65,8 @@ def test_transfer(self, story_client: StoryClient): assert isinstance(response["tx_hash"], str) # Get balances after transfer - sender_wip_after = story_client.WIP.balance_of(wallet_address) - receiver_wip_after = story_client.WIP.balance_of(wallet_address_2) + sender_wip_after = story_client.WIP.balance_of(wallet_address_str) + receiver_wip_after = story_client.WIP.balance_of(wallet_address_2_str) # Verify sender's WIP balance decreased by transfer amount assert sender_wip_after == sender_wip_before - transfer_amount @@ -72,7 +82,7 @@ def test_withdraw(self, story_client: StoryClient): """Test withdrawing WIP to IP""" # Get balances before withdrawal balance_before = story_client.get_wallet_balance() - wip_before = story_client.WIP.balance_of(wallet_address) + wip_before = story_client.WIP.balance_of(wallet_address_str) # Withdraw all WIP response = story_client.WIP.withdraw( @@ -83,7 +93,7 @@ def test_withdraw(self, story_client: StoryClient): assert isinstance(response["tx_hash"], str) # Get balances after withdrawal - wip_after = story_client.WIP.balance_of(wallet_address) + wip_after = story_client.WIP.balance_of(wallet_address_str) balance_after = story_client.get_wallet_balance() # Verify WIP balance is now zero @@ -91,7 +101,7 @@ def test_withdraw(self, story_client: StoryClient): # Calculate gas cost tx_receipt = web3.eth.wait_for_transaction_receipt( - response["tx_hash"], timeout=300 + Hash32(bytes.fromhex(response["tx_hash"][2:])), timeout=300 ) gas_cost = tx_receipt["gasUsed"] * tx_receipt["effectiveGasPrice"] diff --git a/tests/unit/resources/test_royalty.py b/tests/unit/resources/test_royalty.py index 246db0d..47c620b 100644 --- a/tests/unit/resources/test_royalty.py +++ b/tests/unit/resources/test_royalty.py @@ -1,6 +1,7 @@ from unittest.mock import patch import pytest +from ens.ens import HexStr from web3 import Web3 from story_protocol_python_sdk.resources.Royalty import Royalty @@ -103,7 +104,9 @@ def test_pay_royalty_on_behalf_success(royalty_client): with patch( "web3.eth.Eth.send_raw_transaction", return_value=Web3.to_bytes( - hexstr="0xbadf64f2c220e27407c4d2ccbc772fb72c7dc590ac25000dc316e4dc519fbfa2" + hexstr=HexStr( + "0xbadf64f2c220e27407c4d2ccbc772fb72c7dc590ac25000dc316e4dc519fbfa2" + ) ), ): with patch( From 5a7e99716affce9c670cb9808b5757d17ffc25a5 Mon Sep 17 00:00:00 2001 From: Bonnie Date: Tue, 5 Aug 2025 15:17:37 +0800 Subject: [PATCH 3/4] Add type checking instructions to DEVELOPMENT.md with mypy command --- DEVELOPMENT.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index f61ce87..e50bcdd 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -106,6 +106,12 @@ The project uses several tools to maintain code quality: All these tools are automatically run as pre-commit hooks when you commit code. +### Type Checking + +```bash +mypy . +``` + ### Manual Pre-commit Checks To manually run all pre-commit checks: From a2f784a0ce98b1a6e73e53daf2c59309ec73fb1b Mon Sep 17 00:00:00 2001 From: Bonnie Date: Tue, 5 Aug 2025 17:43:13 +0800 Subject: [PATCH 4/4] Fix integration tests --- .../resources/IPAsset.py | 4 +- .../utils/license_terms.py | 4 +- .../integration/test_integration_ip_asset.py | 8 ++-- tests/integration/test_integration_wip.py | 4 +- tests/unit/resources/test_license.py | 44 +++++++++---------- 5 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/story_protocol_python_sdk/resources/IPAsset.py b/src/story_protocol_python_sdk/resources/IPAsset.py index 11928a6..d6e6709 100644 --- a/src/story_protocol_python_sdk/resources/IPAsset.py +++ b/src/story_protocol_python_sdk/resources/IPAsset.py @@ -572,7 +572,7 @@ def register_ip_and_attach_pil_terms( self, nft_contract: str, token_id: int, - license_terms_data: dict, + license_terms_data: list, ip_metadata: dict | None = None, deadline: int | None = None, tx_options: dict | None = None, @@ -582,7 +582,7 @@ def register_ip_and_attach_pil_terms( :param nft_contract str: The address of the NFT collection. :param token_id int: The ID of the NFT. - :param license_terms_data dict: The PIL terms and licensing configuration data to be attached to the IP. + :param license_terms_data list: The PIL terms and licensing configuration data to be attached to the IP. :param terms dict: The PIL terms to be used for the licensing. :param transferable bool: Indicates whether the license is transferable or not. :param royalty_policy str: The address of the royalty policy contract which required to StoryProtocol in advance. diff --git a/src/story_protocol_python_sdk/utils/license_terms.py b/src/story_protocol_python_sdk/utils/license_terms.py index ad05e43..05cd049 100644 --- a/src/story_protocol_python_sdk/utils/license_terms.py +++ b/src/story_protocol_python_sdk/utils/license_terms.py @@ -135,9 +135,9 @@ def validate_license_terms(self, params): commercializer_checker_data = params.get( "commercializer_checker_data", ZERO_ADDRESS ) - if isinstance(commercializer_checker_data, HexStr): + if isinstance(commercializer_checker_data, str): params["commercializer_checker_data"] = Web3.to_bytes( - hexstr=commercializer_checker_data + hexstr=HexStr(commercializer_checker_data) ) params["expect_minimum_group_reward_share"] = int( diff --git a/tests/integration/test_integration_ip_asset.py b/tests/integration/test_integration_ip_asset.py index 462c555..ff9a5a0 100644 --- a/tests/integration/test_integration_ip_asset.py +++ b/tests/integration/test_integration_ip_asset.py @@ -357,8 +357,8 @@ def test_register_ip_and_attach_pil_terms( nft_contract=nft_collection, token_id=token_id, deadline=1000, - license_terms_data={ - 0: { + license_terms_data=[ + { "terms": { "transferable": True, "royalty_policy": ZERO_ADDRESS, @@ -389,7 +389,7 @@ def test_register_ip_and_attach_pil_terms( "expect_group_reward_pool": ZERO_ADDRESS, }, }, - 1: { + { "terms": { "transferable": True, "royalty_policy": ROYALTY_POLICY, @@ -420,7 +420,7 @@ def test_register_ip_and_attach_pil_terms( "expect_group_reward_pool": ZERO_ADDRESS, }, }, - }, + ], ) assert isinstance(result["tx_hash"], str) and result["tx_hash"] diff --git a/tests/integration/test_integration_wip.py b/tests/integration/test_integration_wip.py index f059b44..066be08 100644 --- a/tests/integration/test_integration_wip.py +++ b/tests/integration/test_integration_wip.py @@ -37,7 +37,7 @@ def test_deposit(self, story_client: StoryClient): # Calculate gas cost tx_receipt = web3.eth.wait_for_transaction_receipt( - Hash32(bytes.fromhex(response["tx_hash"][2:])), timeout=300 + Hash32(bytes.fromhex(response["tx_hash"])), timeout=300 ) gas_cost = tx_receipt["gasUsed"] * tx_receipt["effectiveGasPrice"] @@ -101,7 +101,7 @@ def test_withdraw(self, story_client: StoryClient): # Calculate gas cost tx_receipt = web3.eth.wait_for_transaction_receipt( - Hash32(bytes.fromhex(response["tx_hash"][2:])), timeout=300 + Hash32(bytes.fromhex(response["tx_hash"])), timeout=300 ) gas_cost = tx_receipt["gasUsed"] * tx_receipt["effectiveGasPrice"] diff --git a/tests/unit/resources/test_license.py b/tests/unit/resources/test_license.py index d2fdb50..5ce788e 100644 --- a/tests/unit/resources/test_license.py +++ b/tests/unit/resources/test_license.py @@ -78,7 +78,9 @@ def license_client(mock_web3, mock_account): class TestPILTermsRegistration: """Tests for PIL (Programmable IP License) terms registration.""" - def test_register_pil_terms_license_terms_id_registered(self, license_client): + def test_register_pil_terms_license_terms_id_registered( + self, license_client: License + ): with patch.object( license_client.license_template_client, "getLicenseTermsId", return_value=1 ), patch.object( @@ -91,27 +93,25 @@ def test_register_pil_terms_license_terms_id_registered(self, license_client): return_value=True, ): - license_terms = { - "default_minting_fee": 1513, - "currency": VALID_ADDRESS, - "royalty_policy": VALID_ADDRESS, - "transferable": False, - "expiration": 0, - "commercial_use": True, - "commercial_attribution": False, - "commercializer_checker": ZERO_ADDRESS, - "commercializer_checker_data": "0x", - "commercial_rev_share": 0, - "commercial_rev_ceiling": 0, - "derivatives_allowed": False, - "derivatives_attribution": False, - "derivatives_approval": False, - "derivatives_reciprocal": False, - "derivative_rev_ceiling": 0, - "uri": "", - } - - response = license_client.register_pil_terms(**license_terms) + response = license_client.register_pil_terms( + default_minting_fee=1513, + currency=VALID_ADDRESS, + royalty_policy=VALID_ADDRESS, + transferable=False, + expiration=0, + commercial_use=True, + commercial_attribution=False, + commercializer_checker=ZERO_ADDRESS, + commercializer_checker_data="0x", + commercial_rev_share=0, + commercial_rev_ceiling=0, + derivatives_allowed=False, + derivatives_attribution=False, + derivatives_approval=False, + derivatives_reciprocal=False, + derivative_rev_ceiling=0, + uri="", + ) assert response["license_terms_id"] == 1 assert "tx_hash" not in response