diff --git a/src/story_protocol_python_sdk/abi/AccessController/AccessController_client.py b/src/story_protocol_python_sdk/abi/AccessController/AccessController_client.py index 76ddcab..fdf2b8b 100644 --- a/src/story_protocol_python_sdk/abi/AccessController/AccessController_client.py +++ b/src/story_protocol_python_sdk/abi/AccessController/AccessController_client.py @@ -23,23 +23,18 @@ def __init__(self, web3: Web3): self.contract = self.web3.eth.contract(address=contract_address, abi=abi) def setAllPermissions(self, ipAccount, signer, permission): - return self.contract.functions.setAllPermissions(ipAccount, signer, permission).transact() def build_setAllPermissions_transaction(self, ipAccount, signer, permission, tx_params): return self.contract.functions.setAllPermissions(ipAccount, signer, permission).build_transaction(tx_params) - def setTransientBatchPermissions(self, permissions): - return self.contract.functions.setTransientBatchPermissions(permissions).transact() def build_setTransientBatchPermissions_transaction(self, permissions, tx_params): return self.contract.functions.setTransientBatchPermissions(permissions).build_transaction(tx_params) - def setTransientPermission(self, ipAccount, signer, to, func, permission): - return self.contract.functions.setTransientPermission(ipAccount, signer, to, func, permission).transact() def build_setTransientPermission_transaction(self, ipAccount, signer, to, func, permission, tx_params): diff --git a/src/story_protocol_python_sdk/abi/ArbitrationPolicyUMA/ArbitrationPolicyUMA_client.py b/src/story_protocol_python_sdk/abi/ArbitrationPolicyUMA/ArbitrationPolicyUMA_client.py index f5af62d..35dd083 100644 --- a/src/story_protocol_python_sdk/abi/ArbitrationPolicyUMA/ArbitrationPolicyUMA_client.py +++ b/src/story_protocol_python_sdk/abi/ArbitrationPolicyUMA/ArbitrationPolicyUMA_client.py @@ -23,17 +23,12 @@ def __init__(self, web3: Web3): self.contract = self.web3.eth.contract(address=contract_address, abi=abi) def maxBonds(self, token): - return self.contract.functions.maxBonds(token).call() - - def maxLiveness(self, ): - + def maxLiveness(self): return self.contract.functions.maxLiveness().call() - - def minLiveness(self, ): - + def minLiveness(self): return self.contract.functions.minLiveness().call() \ No newline at end of file diff --git a/src/story_protocol_python_sdk/abi/DerivativeWorkflows/DerivativeWorkflows_client.py b/src/story_protocol_python_sdk/abi/DerivativeWorkflows/DerivativeWorkflows_client.py index 8dd0669..111b7b8 100644 --- a/src/story_protocol_python_sdk/abi/DerivativeWorkflows/DerivativeWorkflows_client.py +++ b/src/story_protocol_python_sdk/abi/DerivativeWorkflows/DerivativeWorkflows_client.py @@ -23,39 +23,30 @@ def __init__(self, web3: Web3): self.contract = self.web3.eth.contract(address=contract_address, abi=abi) def mintAndRegisterIpAndMakeDerivative(self, spgNftContract, derivData, ipMetadata, recipient, allowDuplicates): - return self.contract.functions.mintAndRegisterIpAndMakeDerivative(spgNftContract, derivData, ipMetadata, recipient, allowDuplicates).transact() def build_mintAndRegisterIpAndMakeDerivative_transaction(self, spgNftContract, derivData, ipMetadata, recipient, allowDuplicates, tx_params): return self.contract.functions.mintAndRegisterIpAndMakeDerivative(spgNftContract, derivData, ipMetadata, recipient, allowDuplicates).build_transaction(tx_params) - def mintAndRegisterIpAndMakeDerivativeWithLicenseTokens(self, spgNftContract, licenseTokenIds, royaltyContext, maxRts, ipMetadata, recipient, allowDuplicates): - return self.contract.functions.mintAndRegisterIpAndMakeDerivativeWithLicenseTokens(spgNftContract, licenseTokenIds, royaltyContext, maxRts, ipMetadata, recipient, allowDuplicates).transact() def build_mintAndRegisterIpAndMakeDerivativeWithLicenseTokens_transaction(self, spgNftContract, licenseTokenIds, royaltyContext, maxRts, ipMetadata, recipient, allowDuplicates, tx_params): return self.contract.functions.mintAndRegisterIpAndMakeDerivativeWithLicenseTokens(spgNftContract, licenseTokenIds, royaltyContext, maxRts, ipMetadata, recipient, allowDuplicates).build_transaction(tx_params) - def multicall(self, data): - return self.contract.functions.multicall(data).transact() def build_multicall_transaction(self, data, tx_params): return self.contract.functions.multicall(data).build_transaction(tx_params) - def registerIpAndMakeDerivative(self, nftContract, tokenId, derivData, ipMetadata, sigMetadataAndRegister): - return self.contract.functions.registerIpAndMakeDerivative(nftContract, tokenId, derivData, ipMetadata, sigMetadataAndRegister).transact() def build_registerIpAndMakeDerivative_transaction(self, nftContract, tokenId, derivData, ipMetadata, sigMetadataAndRegister, tx_params): return self.contract.functions.registerIpAndMakeDerivative(nftContract, tokenId, derivData, ipMetadata, sigMetadataAndRegister).build_transaction(tx_params) - def registerIpAndMakeDerivativeWithLicenseTokens(self, nftContract, tokenId, licenseTokenIds, royaltyContext, maxRts, ipMetadata, sigMetadataAndRegister): - return self.contract.functions.registerIpAndMakeDerivativeWithLicenseTokens(nftContract, tokenId, licenseTokenIds, royaltyContext, maxRts, ipMetadata, sigMetadataAndRegister).transact() def build_registerIpAndMakeDerivativeWithLicenseTokens_transaction(self, nftContract, tokenId, licenseTokenIds, royaltyContext, maxRts, ipMetadata, sigMetadataAndRegister, tx_params): 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 94f7bb4..19774b0 100644 --- a/src/story_protocol_python_sdk/abi/DisputeModule/DisputeModule_client.py +++ b/src/story_protocol_python_sdk/abi/DisputeModule/DisputeModule_client.py @@ -23,31 +23,24 @@ def __init__(self, web3: Web3): self.contract = self.web3.eth.contract(address=contract_address, abi=abi) def cancelDispute(self, disputeId, data): - return self.contract.functions.cancelDispute(disputeId, data).transact() def build_cancelDispute_transaction(self, disputeId, data, tx_params): return self.contract.functions.cancelDispute(disputeId, data).build_transaction(tx_params) - def raiseDispute(self, targetIpId, disputeEvidenceHash, targetTag, data): - return self.contract.functions.raiseDispute(targetIpId, disputeEvidenceHash, targetTag, data).transact() def build_raiseDispute_transaction(self, targetIpId, disputeEvidenceHash, targetTag, data, tx_params): return self.contract.functions.raiseDispute(targetIpId, disputeEvidenceHash, targetTag, data).build_transaction(tx_params) - def resolveDispute(self, disputeId, data): - return self.contract.functions.resolveDispute(disputeId, data).transact() def build_resolveDispute_transaction(self, disputeId, data, tx_params): return self.contract.functions.resolveDispute(disputeId, data).build_transaction(tx_params) - def isWhitelistedDisputeTag(self, tag): - return self.contract.functions.isWhitelistedDisputeTag(tag).call() \ No newline at end of file diff --git a/src/story_protocol_python_sdk/abi/GroupingWorkflows/GroupingWorkflows_client.py b/src/story_protocol_python_sdk/abi/GroupingWorkflows/GroupingWorkflows_client.py index a72dffd..c31d3ff 100644 --- a/src/story_protocol_python_sdk/abi/GroupingWorkflows/GroupingWorkflows_client.py +++ b/src/story_protocol_python_sdk/abi/GroupingWorkflows/GroupingWorkflows_client.py @@ -23,31 +23,24 @@ def __init__(self, web3: Web3): self.contract = self.web3.eth.contract(address=contract_address, abi=abi) def mintAndRegisterIpAndAttachLicenseAndAddToGroup(self, spgNftContract, groupId, recipient, licensesData, ipMetadata, sigAddToGroup, allowDuplicates): - return self.contract.functions.mintAndRegisterIpAndAttachLicenseAndAddToGroup(spgNftContract, groupId, recipient, licensesData, ipMetadata, sigAddToGroup, allowDuplicates).transact() def build_mintAndRegisterIpAndAttachLicenseAndAddToGroup_transaction(self, spgNftContract, groupId, recipient, licensesData, ipMetadata, sigAddToGroup, allowDuplicates, tx_params): return self.contract.functions.mintAndRegisterIpAndAttachLicenseAndAddToGroup(spgNftContract, groupId, recipient, licensesData, ipMetadata, sigAddToGroup, allowDuplicates).build_transaction(tx_params) - def registerGroupAndAttachLicense(self, groupPool, licenseData): - return self.contract.functions.registerGroupAndAttachLicense(groupPool, licenseData).transact() def build_registerGroupAndAttachLicense_transaction(self, groupPool, licenseData, tx_params): return self.contract.functions.registerGroupAndAttachLicense(groupPool, licenseData).build_transaction(tx_params) - def registerGroupAndAttachLicenseAndAddIps(self, groupPool, ipIds, licenseData): - return self.contract.functions.registerGroupAndAttachLicenseAndAddIps(groupPool, ipIds, licenseData).transact() def build_registerGroupAndAttachLicenseAndAddIps_transaction(self, groupPool, ipIds, licenseData, tx_params): return self.contract.functions.registerGroupAndAttachLicenseAndAddIps(groupPool, ipIds, licenseData).build_transaction(tx_params) - def registerIpAndAttachLicenseAndAddToGroup(self, nftContract, tokenId, groupId, licensesData, ipMetadata, sigMetadataAndAttachAndConfig, sigAddToGroup): - return self.contract.functions.registerIpAndAttachLicenseAndAddToGroup(nftContract, tokenId, groupId, licensesData, ipMetadata, sigMetadataAndAttachAndConfig, sigAddToGroup).transact() def build_registerIpAndAttachLicenseAndAddToGroup_transaction(self, nftContract, tokenId, groupId, licensesData, ipMetadata, sigMetadataAndAttachAndConfig, sigAddToGroup, tx_params): diff --git a/src/story_protocol_python_sdk/abi/IPAccountImpl/IPAccountImpl_client.py b/src/story_protocol_python_sdk/abi/IPAccountImpl/IPAccountImpl_client.py index 2b868d9..d982241 100644 --- a/src/story_protocol_python_sdk/abi/IPAccountImpl/IPAccountImpl_client.py +++ b/src/story_protocol_python_sdk/abi/IPAccountImpl/IPAccountImpl_client.py @@ -12,49 +12,36 @@ def __init__(self, web3: Web3, contract_address=None): self.contract = self.web3.eth.contract(address=contract_address, abi=abi) def execute(self, to, value, data, operation): - return self.contract.functions.execute(to, value, data, operation).transact() def build_execute_transaction(self, to, value, data, operation, tx_params): return self.contract.functions.execute(to, value, data, operation).build_transaction(tx_params) - - # def execute(self, to, value, data): + def execute2(self, to, value, data): + return self.contract.functions.execute(to, value, data).transact() - # return self.contract.functions.execute(to, value, data).transact() - - # def build_execute_transaction(self, to, value, data, tx_params): - # return self.contract.functions.execute(to, value, data).build_transaction(tx_params) - + def build_execute2_transaction(self, to, value, data, tx_params): + return self.contract.functions.execute(to, value, data).build_transaction(tx_params) def executeBatch(self, calls, operation): - return self.contract.functions.executeBatch(calls, operation).transact() def build_executeBatch_transaction(self, calls, operation, tx_params): return self.contract.functions.executeBatch(calls, operation).build_transaction(tx_params) - def executeWithSig(self, to, value, data, signer, deadline, signature): - return self.contract.functions.executeWithSig(to, value, data, signer, deadline, signature).transact() def build_executeWithSig_transaction(self, to, value, data, signer, deadline, signature, tx_params): return self.contract.functions.executeWithSig(to, value, data, signer, deadline, signature).build_transaction(tx_params) - - def owner(self, ): - + def owner(self): return self.contract.functions.owner().call() - - def state(self, ): - + def state(self): return self.contract.functions.state().call() - - def token(self, ): - + def token(self): return self.contract.functions.token().call() \ No newline at end of file diff --git a/src/story_protocol_python_sdk/abi/IPAssetRegistry/IPAssetRegistry_client.py b/src/story_protocol_python_sdk/abi/IPAssetRegistry/IPAssetRegistry_client.py index 10d5e12..5cbe5eb 100644 --- a/src/story_protocol_python_sdk/abi/IPAssetRegistry/IPAssetRegistry_client.py +++ b/src/story_protocol_python_sdk/abi/IPAssetRegistry/IPAssetRegistry_client.py @@ -23,20 +23,15 @@ def __init__(self, web3: Web3): self.contract = self.web3.eth.contract(address=contract_address, abi=abi) def register(self, chainid, tokenContract, tokenId): - return self.contract.functions.register(chainid, tokenContract, tokenId).transact() def build_register_transaction(self, chainid, tokenContract, tokenId, tx_params): return self.contract.functions.register(chainid, tokenContract, tokenId).build_transaction(tx_params) - def ipId(self, chainId, tokenContract, tokenId): - return self.contract.functions.ipId(chainId, tokenContract, tokenId).call() - def isRegistered(self, id): - return self.contract.functions.isRegistered(id).call() \ No newline at end of file diff --git a/src/story_protocol_python_sdk/abi/IpRoyaltyVaultImpl/IpRoyaltyVaultImpl_client.py b/src/story_protocol_python_sdk/abi/IpRoyaltyVaultImpl/IpRoyaltyVaultImpl_client.py index a3b0279..6e40cd0 100644 --- a/src/story_protocol_python_sdk/abi/IpRoyaltyVaultImpl/IpRoyaltyVaultImpl_client.py +++ b/src/story_protocol_python_sdk/abi/IpRoyaltyVaultImpl/IpRoyaltyVaultImpl_client.py @@ -12,17 +12,12 @@ def __init__(self, web3: Web3, contract_address=None): self.contract = self.web3.eth.contract(address=contract_address, abi=abi) def balanceOf(self, account): - return self.contract.functions.balanceOf(account).call() - def claimableRevenue(self, claimer, token): - return self.contract.functions.claimableRevenue(claimer, token).call() - - def ipId(self, ): - + def ipId(self): return self.contract.functions.ipId().call() \ No newline at end of file diff --git a/src/story_protocol_python_sdk/abi/LicenseAttachmentWorkflows/LicenseAttachmentWorkflows_client.py b/src/story_protocol_python_sdk/abi/LicenseAttachmentWorkflows/LicenseAttachmentWorkflows_client.py index 932542b..85c6575 100644 --- a/src/story_protocol_python_sdk/abi/LicenseAttachmentWorkflows/LicenseAttachmentWorkflows_client.py +++ b/src/story_protocol_python_sdk/abi/LicenseAttachmentWorkflows/LicenseAttachmentWorkflows_client.py @@ -23,31 +23,24 @@ def __init__(self, web3: Web3): self.contract = self.web3.eth.contract(address=contract_address, abi=abi) def mintAndRegisterIpAndAttachPILTerms(self, spgNftContract, recipient, ipMetadata, licenseTermsData, allowDuplicates): - return self.contract.functions.mintAndRegisterIpAndAttachPILTerms(spgNftContract, recipient, ipMetadata, licenseTermsData, allowDuplicates).transact() def build_mintAndRegisterIpAndAttachPILTerms_transaction(self, spgNftContract, recipient, ipMetadata, licenseTermsData, allowDuplicates, tx_params): return self.contract.functions.mintAndRegisterIpAndAttachPILTerms(spgNftContract, recipient, ipMetadata, licenseTermsData, allowDuplicates).build_transaction(tx_params) - def multicall(self, data): - return self.contract.functions.multicall(data).transact() def build_multicall_transaction(self, data, tx_params): return self.contract.functions.multicall(data).build_transaction(tx_params) - def registerIpAndAttachPILTerms(self, nftContract, tokenId, ipMetadata, licenseTermsData, sigMetadataAndAttachAndConfig): - return self.contract.functions.registerIpAndAttachPILTerms(nftContract, tokenId, ipMetadata, licenseTermsData, sigMetadataAndAttachAndConfig).transact() def build_registerIpAndAttachPILTerms_transaction(self, nftContract, tokenId, ipMetadata, licenseTermsData, sigMetadataAndAttachAndConfig, tx_params): return self.contract.functions.registerIpAndAttachPILTerms(nftContract, tokenId, ipMetadata, licenseTermsData, sigMetadataAndAttachAndConfig).build_transaction(tx_params) - def registerPILTermsAndAttach(self, ipId, licenseTermsData, sigAttachAndConfig): - return self.contract.functions.registerPILTermsAndAttach(ipId, licenseTermsData, sigAttachAndConfig).transact() def build_registerPILTermsAndAttach_transaction(self, ipId, licenseTermsData, sigAttachAndConfig, tx_params): diff --git a/src/story_protocol_python_sdk/abi/LicenseRegistry/LicenseRegistry_client.py b/src/story_protocol_python_sdk/abi/LicenseRegistry/LicenseRegistry_client.py index 925c212..f9135a7 100644 --- a/src/story_protocol_python_sdk/abi/LicenseRegistry/LicenseRegistry_client.py +++ b/src/story_protocol_python_sdk/abi/LicenseRegistry/LicenseRegistry_client.py @@ -23,17 +23,12 @@ def __init__(self, web3: Web3): self.contract = self.web3.eth.contract(address=contract_address, abi=abi) def exists(self, licenseTemplate, licenseTermsId): - return self.contract.functions.exists(licenseTemplate, licenseTermsId).call() - def getRoyaltyPercent(self, ipId, licenseTemplate, licenseTermsId): - return self.contract.functions.getRoyaltyPercent(ipId, licenseTemplate, licenseTermsId).call() - def hasIpAttachedLicenseTerms(self, ipId, licenseTemplate, licenseTermsId): - return self.contract.functions.hasIpAttachedLicenseTerms(ipId, licenseTemplate, licenseTermsId).call() \ No newline at end of file diff --git a/src/story_protocol_python_sdk/abi/LicenseToken/LicenseToken_client.py b/src/story_protocol_python_sdk/abi/LicenseToken/LicenseToken_client.py index 5cabbdd..40f098e 100644 --- a/src/story_protocol_python_sdk/abi/LicenseToken/LicenseToken_client.py +++ b/src/story_protocol_python_sdk/abi/LicenseToken/LicenseToken_client.py @@ -23,7 +23,6 @@ def __init__(self, web3: Web3): self.contract = self.web3.eth.contract(address=contract_address, abi=abi) def ownerOf(self, tokenId): - return self.contract.functions.ownerOf(tokenId).call() \ No newline at end of file diff --git a/src/story_protocol_python_sdk/abi/LicensingModule/LicensingModule_client.py b/src/story_protocol_python_sdk/abi/LicensingModule/LicensingModule_client.py index f6acc49..9914d28 100644 --- a/src/story_protocol_python_sdk/abi/LicensingModule/LicensingModule_client.py +++ b/src/story_protocol_python_sdk/abi/LicensingModule/LicensingModule_client.py @@ -23,47 +23,36 @@ def __init__(self, web3: Web3): self.contract = self.web3.eth.contract(address=contract_address, abi=abi) def attachLicenseTerms(self, ipId, licenseTemplate, licenseTermsId): - return self.contract.functions.attachLicenseTerms(ipId, licenseTemplate, licenseTermsId).transact() def build_attachLicenseTerms_transaction(self, ipId, licenseTemplate, licenseTermsId, tx_params): return self.contract.functions.attachLicenseTerms(ipId, licenseTemplate, licenseTermsId).build_transaction(tx_params) - def mintLicenseTokens(self, licensorIpId, licenseTemplate, licenseTermsId, amount, receiver, royaltyContext, maxMintingFee, maxRevenueShare): - return self.contract.functions.mintLicenseTokens(licensorIpId, licenseTemplate, licenseTermsId, amount, receiver, royaltyContext, maxMintingFee, maxRevenueShare).transact() def build_mintLicenseTokens_transaction(self, licensorIpId, licenseTemplate, licenseTermsId, amount, receiver, royaltyContext, maxMintingFee, maxRevenueShare, tx_params): return self.contract.functions.mintLicenseTokens(licensorIpId, licenseTemplate, licenseTermsId, amount, receiver, royaltyContext, maxMintingFee, maxRevenueShare).build_transaction(tx_params) - def registerDerivative(self, childIpId, parentIpIds, licenseTermsIds, licenseTemplate, royaltyContext, maxMintingFee, maxRts, maxRevenueShare): - return self.contract.functions.registerDerivative(childIpId, parentIpIds, licenseTermsIds, licenseTemplate, royaltyContext, maxMintingFee, maxRts, maxRevenueShare).transact() def build_registerDerivative_transaction(self, childIpId, parentIpIds, licenseTermsIds, licenseTemplate, royaltyContext, maxMintingFee, maxRts, maxRevenueShare, tx_params): return self.contract.functions.registerDerivative(childIpId, parentIpIds, licenseTermsIds, licenseTemplate, royaltyContext, maxMintingFee, maxRts, maxRevenueShare).build_transaction(tx_params) - def registerDerivativeWithLicenseTokens(self, childIpId, licenseTokenIds, royaltyContext, maxRts): - return self.contract.functions.registerDerivativeWithLicenseTokens(childIpId, licenseTokenIds, royaltyContext, maxRts).transact() def build_registerDerivativeWithLicenseTokens_transaction(self, childIpId, licenseTokenIds, royaltyContext, maxRts, tx_params): return self.contract.functions.registerDerivativeWithLicenseTokens(childIpId, licenseTokenIds, royaltyContext, maxRts).build_transaction(tx_params) - def setLicensingConfig(self, ipId, licenseTemplate, licenseTermsId, licensingConfig): - return self.contract.functions.setLicensingConfig(ipId, licenseTemplate, licenseTermsId, licensingConfig).transact() def build_setLicensingConfig_transaction(self, ipId, licenseTemplate, licenseTermsId, licensingConfig, tx_params): return self.contract.functions.setLicensingConfig(ipId, licenseTemplate, licenseTermsId, licensingConfig).build_transaction(tx_params) - def predictMintingLicenseFee(self, licensorIpId, licenseTemplate, licenseTermsId, amount, receiver, royaltyContext): - return self.contract.functions.predictMintingLicenseFee(licensorIpId, licenseTemplate, licenseTermsId, amount, receiver, royaltyContext).call() \ No newline at end of file diff --git a/src/story_protocol_python_sdk/abi/MockERC20/MockERC20_client.py b/src/story_protocol_python_sdk/abi/MockERC20/MockERC20_client.py index 5b94d51..d7eab76 100644 --- a/src/story_protocol_python_sdk/abi/MockERC20/MockERC20_client.py +++ b/src/story_protocol_python_sdk/abi/MockERC20/MockERC20_client.py @@ -23,15 +23,12 @@ def __init__(self, web3: Web3): self.contract = self.web3.eth.contract(address=contract_address, abi=abi) def transfer(self, to, value): - return self.contract.functions.transfer(to, value).transact() def build_transfer_transaction(self, to, value, tx_params): return self.contract.functions.transfer(to, value).build_transaction(tx_params) - def balanceOf(self, account): - return self.contract.functions.balanceOf(account).call() \ No newline at end of file diff --git a/src/story_protocol_python_sdk/abi/ModuleRegistry/ModuleRegistry_client.py b/src/story_protocol_python_sdk/abi/ModuleRegistry/ModuleRegistry_client.py index f3ae356..f907dcc 100644 --- a/src/story_protocol_python_sdk/abi/ModuleRegistry/ModuleRegistry_client.py +++ b/src/story_protocol_python_sdk/abi/ModuleRegistry/ModuleRegistry_client.py @@ -23,7 +23,6 @@ def __init__(self, web3: Web3): self.contract = self.web3.eth.contract(address=contract_address, abi=abi) def isRegistered(self, moduleAddress): - return self.contract.functions.isRegistered(moduleAddress).call() \ No newline at end of file diff --git a/src/story_protocol_python_sdk/abi/PILicenseTemplate/PILicenseTemplate_client.py b/src/story_protocol_python_sdk/abi/PILicenseTemplate/PILicenseTemplate_client.py index d263abc..734cb51 100644 --- a/src/story_protocol_python_sdk/abi/PILicenseTemplate/PILicenseTemplate_client.py +++ b/src/story_protocol_python_sdk/abi/PILicenseTemplate/PILicenseTemplate_client.py @@ -23,25 +23,18 @@ def __init__(self, web3: Web3): self.contract = self.web3.eth.contract(address=contract_address, abi=abi) def registerLicenseTerms(self, terms): - return self.contract.functions.registerLicenseTerms(terms).transact() def build_registerLicenseTerms_transaction(self, terms, tx_params): return self.contract.functions.registerLicenseTerms(terms).build_transaction(tx_params) - def exists(self, licenseTermsId): - return self.contract.functions.exists(licenseTermsId).call() - def getLicenseTerms(self, selectedLicenseTermsId): - return self.contract.functions.getLicenseTerms(selectedLicenseTermsId).call() - def getLicenseTermsId(self, terms): - return self.contract.functions.getLicenseTermsId(terms).call() \ No newline at end of file diff --git a/src/story_protocol_python_sdk/abi/RegistrationWorkflows/RegistrationWorkflows_client.py b/src/story_protocol_python_sdk/abi/RegistrationWorkflows/RegistrationWorkflows_client.py index 3a46271..d157cfa 100644 --- a/src/story_protocol_python_sdk/abi/RegistrationWorkflows/RegistrationWorkflows_client.py +++ b/src/story_protocol_python_sdk/abi/RegistrationWorkflows/RegistrationWorkflows_client.py @@ -23,31 +23,24 @@ def __init__(self, web3: Web3): self.contract = self.web3.eth.contract(address=contract_address, abi=abi) def createCollection(self, spgNftInitParams): - return self.contract.functions.createCollection(spgNftInitParams).transact() def build_createCollection_transaction(self, spgNftInitParams, tx_params): return self.contract.functions.createCollection(spgNftInitParams).build_transaction(tx_params) - def mintAndRegisterIp(self, spgNftContract, recipient, ipMetadata, allowDuplicates): - return self.contract.functions.mintAndRegisterIp(spgNftContract, recipient, ipMetadata, allowDuplicates).transact() def build_mintAndRegisterIp_transaction(self, spgNftContract, recipient, ipMetadata, allowDuplicates, tx_params): return self.contract.functions.mintAndRegisterIp(spgNftContract, recipient, ipMetadata, allowDuplicates).build_transaction(tx_params) - def multicall(self, data): - return self.contract.functions.multicall(data).transact() def build_multicall_transaction(self, data, tx_params): return self.contract.functions.multicall(data).build_transaction(tx_params) - def registerIp(self, nftContract, tokenId, ipMetadata, sigMetadata): - return self.contract.functions.registerIp(nftContract, tokenId, ipMetadata, sigMetadata).transact() def build_registerIp_transaction(self, nftContract, tokenId, ipMetadata, sigMetadata, tx_params): diff --git a/src/story_protocol_python_sdk/abi/RoyaltyModule/RoyaltyModule_client.py b/src/story_protocol_python_sdk/abi/RoyaltyModule/RoyaltyModule_client.py index 0c5ded4..18c02ed 100644 --- a/src/story_protocol_python_sdk/abi/RoyaltyModule/RoyaltyModule_client.py +++ b/src/story_protocol_python_sdk/abi/RoyaltyModule/RoyaltyModule_client.py @@ -23,25 +23,18 @@ def __init__(self, web3: Web3): self.contract = self.web3.eth.contract(address=contract_address, abi=abi) def payRoyaltyOnBehalf(self, receiverIpId, payerIpId, token, amount): - return self.contract.functions.payRoyaltyOnBehalf(receiverIpId, payerIpId, token, amount).transact() def build_payRoyaltyOnBehalf_transaction(self, receiverIpId, payerIpId, token, amount, tx_params): return self.contract.functions.payRoyaltyOnBehalf(receiverIpId, payerIpId, token, amount).build_transaction(tx_params) - def ipRoyaltyVaults(self, ipId): - return self.contract.functions.ipRoyaltyVaults(ipId).call() - def isWhitelistedRoyaltyPolicy(self, royaltyPolicy): - return self.contract.functions.isWhitelistedRoyaltyPolicy(royaltyPolicy).call() - def isWhitelistedRoyaltyToken(self, token): - return self.contract.functions.isWhitelistedRoyaltyToken(token).call() \ No newline at end of file diff --git a/src/story_protocol_python_sdk/abi/RoyaltyTokenDistributionWorkflows/RoyaltyTokenDistributionWorkflows_client.py b/src/story_protocol_python_sdk/abi/RoyaltyTokenDistributionWorkflows/RoyaltyTokenDistributionWorkflows_client.py index f6aeff8..98e0fcd 100644 --- a/src/story_protocol_python_sdk/abi/RoyaltyTokenDistributionWorkflows/RoyaltyTokenDistributionWorkflows_client.py +++ b/src/story_protocol_python_sdk/abi/RoyaltyTokenDistributionWorkflows/RoyaltyTokenDistributionWorkflows_client.py @@ -23,39 +23,30 @@ def __init__(self, web3: Web3): self.contract = self.web3.eth.contract(address=contract_address, abi=abi) def distributeRoyaltyTokens(self, ipId, royaltyShares, sigApproveRoyaltyTokens): - return self.contract.functions.distributeRoyaltyTokens(ipId, royaltyShares, sigApproveRoyaltyTokens).transact() def build_distributeRoyaltyTokens_transaction(self, ipId, royaltyShares, sigApproveRoyaltyTokens, tx_params): return self.contract.functions.distributeRoyaltyTokens(ipId, royaltyShares, sigApproveRoyaltyTokens).build_transaction(tx_params) - def mintAndRegisterIpAndAttachPILTermsAndDistributeRoyaltyTokens(self, spgNftContract, recipient, ipMetadata, licenseTermsData, royaltyShares, allowDuplicates): - return self.contract.functions.mintAndRegisterIpAndAttachPILTermsAndDistributeRoyaltyTokens(spgNftContract, recipient, ipMetadata, licenseTermsData, royaltyShares, allowDuplicates).transact() def build_mintAndRegisterIpAndAttachPILTermsAndDistributeRoyaltyTokens_transaction(self, spgNftContract, recipient, ipMetadata, licenseTermsData, royaltyShares, allowDuplicates, tx_params): return self.contract.functions.mintAndRegisterIpAndAttachPILTermsAndDistributeRoyaltyTokens(spgNftContract, recipient, ipMetadata, licenseTermsData, royaltyShares, allowDuplicates).build_transaction(tx_params) - def mintAndRegisterIpAndMakeDerivativeAndDistributeRoyaltyTokens(self, spgNftContract, recipient, ipMetadata, derivData, royaltyShares, allowDuplicates): - return self.contract.functions.mintAndRegisterIpAndMakeDerivativeAndDistributeRoyaltyTokens(spgNftContract, recipient, ipMetadata, derivData, royaltyShares, allowDuplicates).transact() def build_mintAndRegisterIpAndMakeDerivativeAndDistributeRoyaltyTokens_transaction(self, spgNftContract, recipient, ipMetadata, derivData, royaltyShares, allowDuplicates, tx_params): return self.contract.functions.mintAndRegisterIpAndMakeDerivativeAndDistributeRoyaltyTokens(spgNftContract, recipient, ipMetadata, derivData, royaltyShares, allowDuplicates).build_transaction(tx_params) - def registerIpAndAttachPILTermsAndDeployRoyaltyVault(self, nftContract, tokenId, ipMetadata, licenseTermsData, sigMetadataAndAttachAndConfig): - return self.contract.functions.registerIpAndAttachPILTermsAndDeployRoyaltyVault(nftContract, tokenId, ipMetadata, licenseTermsData, sigMetadataAndAttachAndConfig).transact() def build_registerIpAndAttachPILTermsAndDeployRoyaltyVault_transaction(self, nftContract, tokenId, ipMetadata, licenseTermsData, sigMetadataAndAttachAndConfig, tx_params): return self.contract.functions.registerIpAndAttachPILTermsAndDeployRoyaltyVault(nftContract, tokenId, ipMetadata, licenseTermsData, sigMetadataAndAttachAndConfig).build_transaction(tx_params) - def registerIpAndMakeDerivativeAndDeployRoyaltyVault(self, nftContract, tokenId, ipMetadata, derivData, sigMetadataAndRegister): - return self.contract.functions.registerIpAndMakeDerivativeAndDeployRoyaltyVault(nftContract, tokenId, ipMetadata, derivData, sigMetadataAndRegister).transact() def build_registerIpAndMakeDerivativeAndDeployRoyaltyVault_transaction(self, nftContract, tokenId, ipMetadata, derivData, sigMetadataAndRegister, tx_params): diff --git a/src/story_protocol_python_sdk/abi/RoyaltyWorkflows/RoyaltyWorkflows_client.py b/src/story_protocol_python_sdk/abi/RoyaltyWorkflows/RoyaltyWorkflows_client.py index cc8ed76..72850ad 100644 --- a/src/story_protocol_python_sdk/abi/RoyaltyWorkflows/RoyaltyWorkflows_client.py +++ b/src/story_protocol_python_sdk/abi/RoyaltyWorkflows/RoyaltyWorkflows_client.py @@ -23,7 +23,6 @@ def __init__(self, web3: Web3): self.contract = self.web3.eth.contract(address=contract_address, abi=abi) def claimAllRevenue(self, ancestorIpId, claimer, childIpIds, royaltyPolicies, currencyTokens): - return self.contract.functions.claimAllRevenue(ancestorIpId, claimer, childIpIds, royaltyPolicies, currencyTokens).transact() def build_claimAllRevenue_transaction(self, ancestorIpId, claimer, childIpIds, royaltyPolicies, currencyTokens, tx_params): diff --git a/src/story_protocol_python_sdk/abi/SPGNFTImpl/SPGNFTImpl_client.py b/src/story_protocol_python_sdk/abi/SPGNFTImpl/SPGNFTImpl_client.py index 020bb05..e5feeb7 100644 --- a/src/story_protocol_python_sdk/abi/SPGNFTImpl/SPGNFTImpl_client.py +++ b/src/story_protocol_python_sdk/abi/SPGNFTImpl/SPGNFTImpl_client.py @@ -11,13 +11,10 @@ def __init__(self, web3: Web3, contract_address=None): abi = json.load(abi_file) self.contract = self.web3.eth.contract(address=contract_address, abi=abi) - def mintFee(self, ): - + def mintFee(self): return self.contract.functions.mintFee().call() - - def mintFeeToken(self, ): - + def mintFeeToken(self): return self.contract.functions.mintFeeToken().call() \ No newline at end of file diff --git a/src/story_protocol_python_sdk/abi/WIP/WIP_client.py b/src/story_protocol_python_sdk/abi/WIP/WIP_client.py index 7bb4933..2d10b9c 100644 --- a/src/story_protocol_python_sdk/abi/WIP/WIP_client.py +++ b/src/story_protocol_python_sdk/abi/WIP/WIP_client.py @@ -23,47 +23,36 @@ def __init__(self, web3: Web3): self.contract = self.web3.eth.contract(address=contract_address, abi=abi) def approve(self, spender, amount): - return self.contract.functions.approve(spender, amount).transact() def build_approve_transaction(self, spender, amount, tx_params): return self.contract.functions.approve(spender, amount).build_transaction(tx_params) - - def deposit(self, ): - + def deposit(self): return self.contract.functions.deposit().transact() def build_deposit_transaction(self, tx_params): return self.contract.functions.deposit().build_transaction(tx_params) - def transfer(self, to, amount): - return self.contract.functions.transfer(to, amount).transact() def build_transfer_transaction(self, to, amount, tx_params): return self.contract.functions.transfer(to, amount).build_transaction(tx_params) - def transferFrom(self, from_address, to, amount): - return self.contract.functions.transferFrom(from_address, to, amount).transact() def build_transferFrom_transaction(self, from_address, to, amount, tx_params): return self.contract.functions.transferFrom(from_address, to, amount).build_transaction(tx_params) - def withdraw(self, value): - return self.contract.functions.withdraw(value).transact() def build_withdraw_transaction(self, value, tx_params): return self.contract.functions.withdraw(value).build_transaction(tx_params) - def balanceOf(self, owner): - return self.contract.functions.balanceOf(owner).call() \ No newline at end of file diff --git a/src/story_protocol_python_sdk/resources/Dispute.py b/src/story_protocol_python_sdk/resources/Dispute.py index 543046c..6e7fd49 100644 --- a/src/story_protocol_python_sdk/resources/Dispute.py +++ b/src/story_protocol_python_sdk/resources/Dispute.py @@ -1,11 +1,13 @@ from web3 import Web3 +from eth_abi.abi import encode + +from story_protocol_python_sdk.resources.WIP import WIP from story_protocol_python_sdk.abi.DisputeModule.DisputeModule_client import DisputeModuleClient from story_protocol_python_sdk.abi.ArbitrationPolicyUMA.ArbitrationPolicyUMA_client import ArbitrationPolicyUMAClient + from story_protocol_python_sdk.utils.transaction_utils import build_and_send_transaction from story_protocol_python_sdk.utils.ipfs import convert_cid_to_hash_ipfs -from eth_abi.abi import encode -from story_protocol_python_sdk.resources.WIP import WIP -ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" +from story_protocol_python_sdk.utils.constants import ZERO_ADDRESS class Dispute: """ @@ -22,7 +24,7 @@ def __init__(self, web3: Web3, account, chain_id: int): self.dispute_module_client = DisputeModuleClient(web3) self.arbitration_policy_uma_client = ArbitrationPolicyUMAClient(web3) - self.WIP = WIP(web3, account, chain_id) + self.wip = WIP(web3, account, chain_id) def _validate_address(self, address: str) -> str: """ @@ -36,7 +38,7 @@ def _validate_address(self, address: str) -> str: raise ValueError(f"Invalid address: {address}.") return address - def raiseDispute(self, target_ip_id: str, target_tag: str, cid: str, liveness: int, bond: int, tx_options: dict = None) -> dict: + def raise_dispute(self, target_ip_id: str, target_tag: str, cid: str, liveness: int, bond: int, tx_options: dict = None) -> dict: """ Raises a dispute on a given IP ID. @@ -73,7 +75,7 @@ def raiseDispute(self, target_ip_id: str, target_tag: str, cid: str, liveness: i if bond > max_bonds: raise ValueError(f"Bond must be less than {max_bonds}.") - deposit_response = self.WIP.deposit( + deposit_response = self.wip.deposit( amount=bond ) @@ -101,17 +103,17 @@ def raiseDispute(self, target_ip_id: str, target_tag: str, cid: str, liveness: i tx_options=tx_options ) - dispute_id = self._parse_tx_dispute_raised_event(response['txReceipt']) + dispute_id = self._parse_tx_dispute_raised_event(response['tx_receipt']) return { - 'txHash': response['txHash'], - 'disputeId': dispute_id if dispute_id else None + 'tx_hash': response['tx_hash'], + 'dispute_id': dispute_id if dispute_id else None } except Exception as e: raise ValueError(f"Failed to raise dispute: {str(e)}") - def cancelDispute(self, dispute_id: int, data: str = "0x", tx_options: dict = None) -> dict: + def cancel_dispute(self, dispute_id: int, data: str = "0x", tx_options: dict = None) -> dict: """ Cancels an ongoing dispute. @@ -131,13 +133,13 @@ def cancelDispute(self, dispute_id: int, data: str = "0x", tx_options: dict = No ) return { - 'txHash': response['txHash'] + 'tx_hash': response['tx_hash'] } except Exception as e: raise ValueError(f"Failed to cancel dispute: {str(e)}") - def resolveDispute(self, dispute_id: int, data: str, tx_options: dict = None) -> dict: + def resolve_dispute(self, dispute_id: int, data: str, tx_options: dict = None) -> dict: """ Resolves a dispute after it has been judged. @@ -157,13 +159,13 @@ def resolveDispute(self, dispute_id: int, data: str, tx_options: dict = None) -> ) return { - 'txHash': response['txHash'] + 'tx_hash': response['tx_hash'] } except Exception as e: raise ValueError(f"Failed to resolve dispute: {str(e)}") - def tagIfRelatedIpInfringed(self, infringement_tags: list, tx_options: dict = None) -> list: + def tag_if_related_ip_infringed(self, infringement_tags: list, tx_options: dict = None) -> list: """ Tags a derivative if a parent has been tagged with an infringement tag. @@ -188,19 +190,19 @@ def tagIfRelatedIpInfringed(self, infringement_tags: list, tx_options: dict = No tx_options=tx_options ) - tx_hashes.append(response['txHash']) + tx_hashes.append(response['tx_hash']) return tx_hashes 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) -> dict: + def _parse_tx_dispute_raised_event(self, tx_receipt: dict) -> int: """ Parse the DisputeRaised event from a transaction receipt. :param tx_receipt dict: The transaction receipt. - :return dict: The dispute ID from the event. + :return int: The dispute ID from the event. """ event_signature = self.web3.keccak( text="DisputeRaised(uint256,address,address,uint256,address,bytes32,bytes32,bytes)" diff --git a/src/story_protocol_python_sdk/resources/IPAccount.py b/src/story_protocol_python_sdk/resources/IPAccount.py index cea4bd6..2b4e05b 100644 --- a/src/story_protocol_python_sdk/resources/IPAccount.py +++ b/src/story_protocol_python_sdk/resources/IPAccount.py @@ -29,11 +29,11 @@ def __init__(self, web3: Web3, account, chain_id: int): self.core_metadata_module_client = CoreMetadataModuleClient(web3) self.mock_erc20_client = MockERC20Client(web3) - def getToken(self, ip_id: str) -> dict: + def get_token(self, ip_id: str) -> dict: """Retrieve token information associated with an IP account. :param ip_id str: The IP ID to query. - :returns dict: Dictionary containing chainId, tokenContract, and tokenId. + :returns dict: Dictionary containing chain_id, token_contract, and token_id. :raises ValueError: If the IP ID is invalid. """ try: @@ -41,9 +41,9 @@ def getToken(self, ip_id: str) -> dict: ip_account_client = IPAccountImplClient(self.web3, contract_address=checksum_address) chain_id, token_contract, token_id = ip_account_client.token() return { - 'chainId': chain_id, - 'tokenContract': token_contract, - 'tokenId': token_id + 'chain_id': chain_id, + 'token_contract': token_contract, + 'token_id': token_id } except ValueError: # Catch ValueError from to_checksum_address raise ValueError(f"Invalid IP id address: {ip_id}") @@ -88,7 +88,7 @@ def execute(self, to: str, value: int, ip_id: str, data: str, tx_options: dict = return response - def executeWithSig(self, ip_id: str, to: str, data: str, signer: str, deadline: int, signature: str, value: int = 0, tx_options: dict = None) -> dict: + def execute_with_sig(self, ip_id: str, to: str, data: str, signer: str, deadline: int, signature: str, value: int = 0, tx_options: dict = None) -> dict: """Execute a signed transaction from the IP Account. :param ip_id str: The IP ID to get IP account. @@ -120,7 +120,7 @@ def executeWithSig(self, ip_id: str, to: str, data: str, signer: str, deadline: return response - def getIpAccountNonce(self, ip_id: str) -> bytes: + def get_ip_account_nonce(self, ip_id: str) -> bytes: """Get the IP Account's internal nonce for transaction ordering. :param ip_id str: The IP ID to query. @@ -158,7 +158,7 @@ def owner(self, ip_id: str) -> str: except Exception as e: raise e - def setIpMetadata(self, ip_id: str, metadata_uri: str, metadata_hash: str, tx_options: dict = None) -> dict: + def set_ip_metadata(self, ip_id: str, metadata_uri: str, metadata_hash: str, tx_options: dict = None) -> dict: """Sets the metadataURI for an IP asset. :param ip_id str: The IP ID to set metadata for. @@ -189,7 +189,7 @@ def setIpMetadata(self, ip_id: str, metadata_uri: str, metadata_hash: str, tx_op except Exception as e: raise e - def transferERC20(self, ip_id: str, tokens: list, tx_options: dict = None) -> dict: + def transfer_erc20(self, ip_id: str, tokens: list, tx_options: dict = 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 ceddc32..df4a66f 100644 --- a/src/story_protocol_python_sdk/resources/IPAsset.py +++ b/src/story_protocol_python_sdk/resources/IPAsset.py @@ -16,10 +16,7 @@ from story_protocol_python_sdk.utils.license_terms import LicenseTerms from story_protocol_python_sdk.utils.transaction_utils import build_and_send_transaction from story_protocol_python_sdk.utils.sign import Sign - -ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" -ZERO_HASH = "0x0000000000000000000000000000000000000000000000000000000000000000" - +from story_protocol_python_sdk.utils.constants import ZERO_ADDRESS, ZERO_HASH class IPAsset: """ @@ -74,8 +71,8 @@ def register( ip_id = self._get_ip_id(nft_contract, token_id) if self._is_registered(ip_id): return { - 'txHash': None, - 'ipId': ip_id + 'tx_hash': None, + 'ip_id': ip_id } req_object = { @@ -145,17 +142,27 @@ def register( tx_options=tx_options ) - ip_registered = self._parse_tx_ip_registered_event(response['txReceipt']) + ip_registered = self._parse_tx_ip_registered_event(response['tx_receipt']) return { - 'txHash': response['txHash'], - 'ipId': ip_registered['ipId'] + 'tx_hash': response['tx_hash'], + 'ip_id': ip_registered['ip_id'] } except Exception as e: raise e - def registerDerivative(self, child_ip_id: str, parent_ip_ids: list, license_terms_ids: list, max_minting_fee: int = 0, max_rts: int = 0, max_revenue_share: int = 0, license_template: str = None, tx_options: dict = None) -> dict: + def register_derivative( + self, + child_ip_id: str, + parent_ip_ids: list, + license_terms_ids: list, + max_minting_fee: int = 0, + max_rts: int = 0, + max_revenue_share: int = 0, + license_template: str = None, + tx_options: dict = None + ) -> dict: """ Registers a derivative directly with parent IP's license terms, without needing license tokens, and attaches the license terms of the parent IPs to the derivative IP. @@ -166,8 +173,10 @@ def registerDerivative(self, child_ip_id: str, parent_ip_ids: list, license_term :param child_ip_id str: The derivative IP ID :param parent_ip_ids list: The parent IP IDs :param license_terms_ids list: The IDs of the license terms that the parent IP supports - :param max_minting_fee int: The maximum minting fee that the caller is willing to pay. if set to 0 then no limit - :param max_rts int: The maximum number of royalty tokens that can be distributed (max: 100,000,000) + :param max_minting_fee int: The maximum minting fee that the caller is willing to pay. + if set to 0 then no limit + :param max_rts int: The maximum number of royalty tokens that can be distributed + (max: 100,000,000) :param max_revenue_share int: The maximum revenue share percentage allowed (0-100,000,000) :param license_template str: [Optional] The license template address :param tx_options dict: [Optional] Transaction options @@ -203,7 +212,7 @@ def registerDerivative(self, child_ip_id: str, parent_ip_ids: list, license_term ) return { - 'txHash': response['txHash'] + 'tx_hash': response['tx_hash'] } except Exception as e: @@ -229,12 +238,13 @@ def _validate_derivative_data(self, derivative_data: dict) -> dict: :return dict: The processed internal derivative data :raises ValueError: If validation fails """ - internal_data = { 'childIpId': derivative_data['childIpId'], 'parentIpIds': derivative_data['parentIpIds'], 'licenseTermsIds': [int(id) for id in derivative_data['licenseTermsIds']], - 'licenseTemplate': derivative_data.get('licenseTemplate') if derivative_data.get('licenseTemplate') is not None else self.pi_license_template_client.contract.address, + 'licenseTemplate': (derivative_data.get('licenseTemplate') + if derivative_data.get('licenseTemplate') is not None + else self.pi_license_template_client.contract.address), 'royaltyContext': ZERO_ADDRESS, 'maxMintingFee': int(derivative_data.get('maxMintingFee', 0)), 'maxRts': int(derivative_data.get('maxRts', 0)), @@ -259,24 +269,42 @@ def _validate_derivative_data(self, derivative_data: dict) -> dict: if not self._is_registered(parent_id): raise ValueError(f"The parent IP with id {parent_id} is not registered.") - if not self.license_registry_client.hasIpAttachedLicenseTerms(parent_id, internal_data['licenseTemplate'], terms_id): - raise ValueError(f"License terms id {terms_id} must be attached to the parent ipId {parent_id} before registering derivative.") + if not self.license_registry_client.hasIpAttachedLicenseTerms( + parent_id, internal_data['licenseTemplate'], terms_id + ): + raise ValueError( + f"License terms id {terms_id} must be attached to the parent ipId " + f"{parent_id} before registering derivative." + ) - royalty_percent = self.license_registry_client.getRoyaltyPercent(parent_id, internal_data['licenseTemplate'], terms_id) + royalty_percent = self.license_registry_client.getRoyaltyPercent( + parent_id, internal_data['licenseTemplate'], terms_id + ) if internal_data['maxRevenueShare'] != 0 and royalty_percent > internal_data['maxRevenueShare']: - raise ValueError(f"The royalty percent for the parent IP with id {parent_id} is greater than the maximum revenue share {internal_data['maxRevenueShare']}.") + raise ValueError( + f"The royalty percent for the parent IP with id {parent_id} is greater " + f"than the maximum revenue share {internal_data['maxRevenueShare']}." + ) return internal_data - def registerDerivativeWithLicenseTokens(self, child_ip_id: str, license_token_ids: list, max_rts: int = 0, tx_options: dict = None) -> dict: + def register_derivative_with_license_tokens( + self, + child_ip_id: str, + license_token_ids: list, + max_rts: int = 0, + tx_options: dict = None + ) -> dict: """ - Registers a derivative with license tokens. The derivative IP is registered with license tokens minted from the parent IP's license terms. + Registers a derivative with license tokens. The derivative IP is registered with license tokens + minted from the parent IP's license terms. The license terms of the parent IPs issued with license tokens are attached to the derivative IP. The caller must be the derivative IP owner or an authorized operator. :param child_ip_id str: The derivative IP ID. :param license_token_ids list: The IDs of the license tokens. - :param max_rts int: The maximum number of royalty tokens that can be distributed to the external royalty policies (max: 100,000,000). + :param max_rts int: The maximum number of royalty tokens that can be distributed to the + external royalty policies (max: 100,000,000). :param tx_options dict: [Optional] The transaction options. :return dict: A dictionary with the transaction hash. """ @@ -304,7 +332,7 @@ def registerDerivativeWithLicenseTokens(self, child_ip_id: str, license_token_id ) return { - 'txHash': response['txHash'] + 'tx_hash': response['tx_hash'] } except Exception as e: @@ -332,7 +360,7 @@ def _validate_license_token_ids(self, license_token_ids: list) -> list: return license_token_ids - def mintAndRegisterIpAssetWithPilTerms( + def mint_and_register_ip_asset_with_pil_terms( self, spg_nft_contract: str, terms: list, @@ -416,7 +444,7 @@ def mintAndRegisterIpAssetWithPilTerms( 'commercialUse': term['terms']['commercial_use'], 'commercialAttribution': term['terms']['commercial_attribution'], 'commercializerChecker': term['terms']['commercializer_checker'], - 'commercializerCheckerData': term['terms']['commercializer_checker_data'], # noqa: E501 + 'commercializerCheckerData': term['terms']['commercializer_checker_data'], 'commercialRevShare': term['terms']['commercial_rev_share'], 'commercialRevCeiling': term['terms']['commercial_rev_ceiling'], 'derivativesAllowed': term['terms']['derivatives_allowed'], @@ -433,10 +461,10 @@ def mintAndRegisterIpAssetWithPilTerms( 'mintingFee': validated_licensing_config['minting_fee'], 'hookData': validated_licensing_config['hook_data'], 'licensingHook': validated_licensing_config['licensing_hook'], - 'commercialRevShare': validated_licensing_config['commercial_rev_share'], # noqa: E501 + 'commercialRevShare': validated_licensing_config['commercial_rev_share'], 'disabled': validated_licensing_config['disabled'], - 'expectMinimumGroupRewardShare': validated_licensing_config['expect_minimum_group_reward_share'], # noqa: E501 - 'expectGroupRewardPool': validated_licensing_config['expect_group_reward_pool'] # noqa: E501 + 'expectMinimumGroupRewardShare': validated_licensing_config['expect_minimum_group_reward_share'], + 'expectGroupRewardPool': validated_licensing_config['expect_group_reward_pool'] } license_terms.append({ @@ -462,7 +490,7 @@ def mintAndRegisterIpAssetWithPilTerms( response = build_and_send_transaction( self.web3, self.account, - self.license_attachment_workflows_client.build_mintAndRegisterIpAndAttachPILTerms_transaction, # noqa: E501 + self.license_attachment_workflows_client.build_mintAndRegisterIpAndAttachPILTerms_transaction, spg_nft_contract, recipient if recipient else self.account.address, metadata, @@ -471,22 +499,22 @@ def mintAndRegisterIpAssetWithPilTerms( tx_options=tx_options ) - ip_registered = self._parse_tx_ip_registered_event(response['txReceipt']) + ip_registered = self._parse_tx_ip_registered_event(response['tx_receipt']) license_terms_ids = self._parse_tx_license_terms_attached_event( - response['txReceipt'] + response['tx_receipt'] ) return { - 'txHash': response['txHash'], - 'ipId': ip_registered['ipId'], - 'licenseTermsIds': license_terms_ids, - 'tokenId': ip_registered['tokenId'] + 'tx_hash': response['tx_hash'], + 'ip_id': ip_registered['ip_id'], + 'license_terms_ids': license_terms_ids, + 'token_id': ip_registered['token_id'] } except Exception as e: raise e - def mintAndRegisterIp( + def mint_and_register_ip( self, spg_nft_contract: str, recipient: str = None, @@ -538,12 +566,12 @@ def mintAndRegisterIp( tx_options=tx_options ) - ip_registered = self._parse_tx_ip_registered_event(response['txReceipt']) + ip_registered = self._parse_tx_ip_registered_event(response['tx_receipt']) return { - 'txHash': response['txHash'], - 'ipId': ip_registered['ipId'], - 'tokenId': ip_registered['tokenId'] + 'tx_hash': response['tx_hash'], + 'ip_id': ip_registered['ip_id'], + 'token_id': ip_registered['token_id'] } except Exception as e: @@ -658,8 +686,8 @@ def mintAndRegisterIp( # tx_options=tx_options # ) - # ip_registered = self._parse_tx_ip_registered_event(response['txReceipt']) - # license_terms_id = self._parse_tx_license_terms_attached_event(response['txReceipt']) + # ip_registered = self._parse_tx_ip_registered_event(response['tx_receipt']) + # license_terms_id = self._parse_tx_license_terms_attached_event(response['tx_receipt']) # return { # 'txHash': response['txHash'], @@ -799,7 +827,7 @@ def mintAndRegisterIp( # tx_options=tx_options # ) # - # ip_registered = self._parse_tx_ip_registered_event(response['txReceipt']) + # ip_registered = self._parse_tx_ip_registered_event(response['tx_receipt']) # # return { # 'txHash': response['txHash'], @@ -848,8 +876,8 @@ def _parse_tx_ip_registered_event(self, tx_receipt: dict) -> int: token_id = int(log['topics'][3].hex(), 16) return { - 'ipId': self.web3.to_checksum_address(ip_id), - 'tokenId': token_id + 'ip_id': self.web3.to_checksum_address(ip_id), + 'token_id': token_id } return None diff --git a/src/story_protocol_python_sdk/resources/License.py b/src/story_protocol_python_sdk/resources/License.py index d793963..1090ed7 100644 --- a/src/story_protocol_python_sdk/resources/License.py +++ b/src/story_protocol_python_sdk/resources/License.py @@ -1,4 +1,4 @@ -#src/story_protcol_python_sdk/resources/License.py +# src/story_protcol_python_sdk/resources/License.py from web3 import Web3 @@ -7,10 +7,10 @@ from story_protocol_python_sdk.abi.LicensingModule.LicensingModule_client import LicensingModuleClient from story_protocol_python_sdk.abi.IPAssetRegistry.IPAssetRegistry_client import IPAssetRegistryClient from story_protocol_python_sdk.abi.ModuleRegistry.ModuleRegistry_client import ModuleRegistryClient + from story_protocol_python_sdk.utils.license_terms import LicenseTerms from story_protocol_python_sdk.utils.transaction_utils import build_and_send_transaction - -ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" +from story_protocol_python_sdk.utils.constants import ZERO_ADDRESS class License: """ @@ -27,7 +27,7 @@ def __init__(self, web3: Web3, account, chain_id: int): self.license_template_client = PILicenseTemplateClient(web3) self.license_registry_client = LicenseRegistryClient(web3) - self.licensing_module_client = LicensingModuleClient(web3) + self.licensing_module_client = LicensingModuleClient(web3) self.ip_asset_registry_client = IPAssetRegistryClient(web3) self.module_registry_client = ModuleRegistryClient(web3) @@ -42,25 +42,27 @@ def _get_license_terms_id(self, license_terms: dict) -> int: """ return self.license_template_client.getLicenseTermsId(license_terms) - def registerPILTerms(self, - transferable: bool, - royalty_policy: str, - default_minting_fee: int, - expiration: int, - commercial_use: bool, - commercial_attribution: bool, - commercializer_checker: str, - commercializer_checker_data: str, - commercial_rev_share: int, - commercial_rev_ceiling: int, - derivatives_allowed: bool, - derivatives_attribution: bool, - derivatives_approval: bool, - derivatives_reciprocal: bool, - derivative_rev_ceiling: int, - currency: str, - uri: str, - tx_options: dict = None) -> dict: + def register_pil_terms( + self, + transferable: bool, + royalty_policy: str, + default_minting_fee: int, + expiration: int, + commercial_use: bool, + commercial_attribution: bool, + commercializer_checker: str, + commercializer_checker_data: str, + commercial_rev_share: int, + commercial_rev_ceiling: int, + derivatives_allowed: bool, + derivatives_attribution: bool, + derivatives_approval: bool, + derivatives_reciprocal: bool, + derivative_rev_ceiling: int, + currency: str, + uri: str, + tx_options: dict = None + ) -> dict: """ Registers new license terms and returns the ID of the newly registered license terms. @@ -130,7 +132,7 @@ def registerPILTerms(self, license_terms_id = self._get_license_terms_id(license_terms) if (license_terms_id is not None) and (license_terms_id != 0): - return {'licenseTermsId': license_terms_id} + return {'license_terms_id': license_terms_id} response = build_and_send_transaction( self.web3, @@ -140,16 +142,16 @@ def registerPILTerms(self, tx_options=tx_options ) - target_logs = self._parse_tx_license_terms_registered_event(response['txReceipt']) + target_logs = self._parse_tx_license_terms_registered_event(response['tx_receipt']) return { - 'txHash': response['txHash'], - 'licenseTermsId': target_logs + 'tx_hash': response['tx_hash'], + 'license_terms_id': target_logs } except Exception as e: raise e - def registerNonComSocialRemixingPIL(self, tx_options: dict = None) -> dict: + def register_non_com_social_remixing_pil(self, tx_options: dict = None) -> dict: """ Convenient function to register a PIL non-commercial social remix license to the registry. @@ -157,11 +159,12 @@ def registerNonComSocialRemixingPIL(self, tx_options: dict = None) -> dict: :return dict: A dictionary with the transaction hash and the license terms ID. """ try: - license_terms = self.license_terms_util.get_license_term_by_type(self.license_terms_util.PIL_TYPE['NON_COMMERCIAL_REMIX']) + license_terms = self.license_terms_util.get_license_term_by_type( + self.license_terms_util.PIL_TYPE['NON_COMMERCIAL_REMIX']) license_terms_id = self._get_license_terms_id(license_terms) if (license_terms_id is not None) and (license_terms_id != 0): - return {'licenseTermsId': license_terms_id} + return {'license_terms_id': license_terms_id} response = build_and_send_transaction( self.web3, @@ -171,16 +174,22 @@ def registerNonComSocialRemixingPIL(self, tx_options: dict = None) -> dict: tx_options=tx_options ) - target_logs = self._parse_tx_license_terms_registered_event(response['txReceipt']) + target_logs = self._parse_tx_license_terms_registered_event(response['tx_receipt']) return { - 'txHash': response['txHash'], - 'licenseTermsId': target_logs + 'tx_hash': response['tx_hash'], + 'license_terms_id': target_logs } except Exception as e: raise e - def registerCommercialUsePIL(self, default_minting_fee: int, currency: str, royalty_policy: str = None, tx_options: dict = None) -> dict: + def register_commercial_use_pil( + self, + default_minting_fee: int, + currency: str, + royalty_policy: str = None, + tx_options: dict = None + ) -> dict: """ Convenient function to register a PIL commercial use license to the registry. @@ -191,15 +200,16 @@ def registerCommercialUsePIL(self, default_minting_fee: int, currency: str, roya :return dict: A dictionary with the transaction hash and the license terms ID. """ try: - complete_license_terms = self.license_terms_util.get_license_term_by_type(self.license_terms_util.PIL_TYPE['COMMERCIAL_USE'], { - 'defaultMintingFee': default_minting_fee, - 'currency': currency, - 'royaltyPolicyAddress': royalty_policy, - }) + complete_license_terms = self.license_terms_util.get_license_term_by_type( + self.license_terms_util.PIL_TYPE['COMMERCIAL_USE'], { + 'defaultMintingFee': default_minting_fee, + 'currency': currency, + 'royaltyPolicyAddress': royalty_policy, + }) license_terms_id = self._get_license_terms_id(complete_license_terms) if (license_terms_id is not None) and (license_terms_id != 0): - return {'licenseTermsId': license_terms_id} + return {'license_terms_id': license_terms_id} response = build_and_send_transaction( self.web3, @@ -209,19 +219,26 @@ def registerCommercialUsePIL(self, default_minting_fee: int, currency: str, roya tx_options=tx_options ) - if not response['txReceipt'].logs: + if not response['tx_receipt'].logs: return None - target_logs = self._parse_tx_license_terms_registered_event(response['txReceipt']) + target_logs = self._parse_tx_license_terms_registered_event(response['tx_receipt']) return { - 'txHash': response['txHash'], - 'licenseTermsId': target_logs + 'tx_hash': response['tx_hash'], + 'license_terms_id': target_logs } except Exception as e: raise e - def registerCommercialRemixPIL(self, default_minting_fee: int, currency: str, commercial_rev_share: int, royalty_policy: str, tx_options: dict = None) -> dict: + def register_commercial_remix_pil( + self, + default_minting_fee: int, + currency: str, + commercial_rev_share: int, + royalty_policy: str, + tx_options: dict = None + ) -> dict: """ Convenient function to register a PIL commercial remix license to the registry. @@ -233,16 +250,17 @@ def registerCommercialRemixPIL(self, default_minting_fee: int, currency: str, co :return dict: A dictionary with the transaction hash and the license terms ID. """ try: - complete_license_terms = self.license_terms_util.get_license_term_by_type(self.license_terms_util.PIL_TYPE['COMMERCIAL_REMIX'], { - 'defaultMintingFee': default_minting_fee, - 'currency': currency, - 'commercialRevShare': commercial_rev_share, - 'royaltyPolicyAddress': royalty_policy, - }) + complete_license_terms = self.license_terms_util.get_license_term_by_type( + self.license_terms_util.PIL_TYPE['COMMERCIAL_REMIX'], { + 'defaultMintingFee': default_minting_fee, + 'currency': currency, + 'commercialRevShare': commercial_rev_share, + 'royaltyPolicyAddress': royalty_policy, + }) license_terms_id = self._get_license_terms_id(complete_license_terms) if license_terms_id and license_terms_id != 0: - return {'licenseTermsId': license_terms_id} + return {'license_terms_id': license_terms_id} response = build_and_send_transaction( self.web3, @@ -252,13 +270,13 @@ def registerCommercialRemixPIL(self, default_minting_fee: int, currency: str, co tx_options=tx_options ) - if not response['txReceipt'].logs: + if not response['tx_receipt'].logs: return None - target_logs = self._parse_tx_license_terms_registered_event(response['txReceipt']) + target_logs = self._parse_tx_license_terms_registered_event(response['tx_receipt']) return { - 'txHash': response['txHash'], - 'licenseTermsId': target_logs + 'tx_hash': response['tx_hash'], + 'license_terms_id': target_logs } except Exception as e: @@ -279,7 +297,13 @@ def _parse_tx_license_terms_registered_event(self, tx_receipt: dict) -> int: return None - def attachLicenseTerms(self, ip_id: str, license_template: str, license_terms_id: int, tx_options: dict = None) -> dict: + def attach_license_terms( + self, + ip_id: str, + license_template: str, + license_terms_id: int, + tx_options: dict = None + ) -> dict: """ Attaches license terms to an IP. @@ -301,9 +325,11 @@ def attachLicenseTerms(self, ip_id: str, license_template: str, license_terms_id if not is_existed: raise ValueError(f"License terms id {license_terms_id} do not exist.") - is_attached_license_terms = self.license_registry_client.hasIpAttachedLicenseTerms(ip_id, license_template, license_terms_id) + is_attached_license_terms = self.license_registry_client.hasIpAttachedLicenseTerms( + ip_id, license_template, license_terms_id) if is_attached_license_terms: - raise ValueError(f"License terms id {license_terms_id} is already attached to the IP with id {ip_id}.") + raise ValueError( + f"License terms id {license_terms_id} is already attached to the IP with id {ip_id}.") response = build_and_send_transaction( self.web3, @@ -315,12 +341,22 @@ def attachLicenseTerms(self, ip_id: str, license_template: str, license_terms_id tx_options=tx_options ) - return {'txHash': response['txHash']} + return {'tx_hash': response['tx_hash']} except Exception as e: raise e - def mintLicenseTokens(self, licensor_ip_id: str, license_template: str, license_terms_id: int, amount: int, receiver: str, max_minting_fee: int = 0, max_revenue_share: int = 0, tx_options: dict = None) -> dict: + def mint_license_tokens( + self, + licensor_ip_id: str, + license_template: str, + license_terms_id: int, + amount: int, + receiver: str, + max_minting_fee: int = 0, + max_revenue_share: int = 0, + tx_options: dict = None + ) -> dict: """ Mints license tokens for the license terms attached to an IP. @@ -335,10 +371,10 @@ def mintLicenseTokens(self, licensor_ip_id: str, license_template: str, license_ :return dict: A dictionary with the transaction hash and the license token IDs. """ try: - if not Web3.is_address(license_template): + if not self.web3.is_address(license_template): raise ValueError(f'Address "{license_template}" is invalid.') - if not Web3.is_address(receiver): + if not self.web3.is_address(receiver): raise ValueError(f'Address "{receiver}" is invalid.') is_registered = self.ip_asset_registry_client.isRegistered(licensor_ip_id) @@ -349,9 +385,11 @@ def mintLicenseTokens(self, licensor_ip_id: str, license_template: str, license_ if not is_existed: raise ValueError(f"License terms id {license_terms_id} do not exist.") - is_attached_license_terms = self.license_registry_client.hasIpAttachedLicenseTerms(licensor_ip_id, license_template, license_terms_id) + is_attached_license_terms = self.license_registry_client.hasIpAttachedLicenseTerms( + licensor_ip_id, license_template, license_terms_id) if not is_attached_license_terms: - raise ValueError(f"License terms id {license_terms_id} is not attached to the IP with id {licensor_ip_id}.") + raise ValueError( + f"License terms id {license_terms_id} is not attached to the IP with id {licensor_ip_id}.") response = build_and_send_transaction( self.web3, @@ -368,11 +406,11 @@ def mintLicenseTokens(self, licensor_ip_id: str, license_template: str, license_ tx_options=tx_options ) - target_logs = self._parse_tx_license_tokens_minted_event(response['txReceipt']) + target_logs = self._parse_tx_license_tokens_minted_event(response['tx_receipt']) return { - 'txHash': response['txHash'], - 'licenseTokenIds': target_logs + 'tx_hash': response['tx_hash'], + 'license_token_ids': target_logs } except Exception as e: @@ -395,19 +433,27 @@ def _parse_tx_license_tokens_minted_event(self, tx_receipt: dict) -> list: return token_ids if token_ids else None - def getLicenseTerms(self, selectedLicenseTermsId: int) -> dict: + def get_license_terms(self, selected_license_terms_id: int) -> dict: """ Gets License Terms of the given ID. - :param selectedLicenseTermsId int: The ID of the license terms to retrieve. + :param selected_license_terms_id int: The ID of the license terms to retrieve. :return dict: An object containing all of the selected license terms. """ try: - return self.license_template_client.getLicenseTerms(selectedLicenseTermsId) + return self.license_template_client.getLicenseTerms(selected_license_terms_id) except Exception as e: raise ValueError(f"Failed to get license terms: {str(e)}") - def predictMintingLicenseFee(self, licensor_ip_id: str, license_terms_id: int, amount: int, license_template: str = None, receiver: str = None, tx_options: dict = None) -> dict: + def predict_minting_license_fee( + self, + licensor_ip_id: str, + license_terms_id: int, + amount: int, + license_template: str = None, + receiver: str = None, + tx_options: dict = None + ) -> dict: """ Pre-compute the minting license fee for the given IP and license terms. @@ -456,7 +502,14 @@ def predictMintingLicenseFee(self, licensor_ip_id: str, license_terms_id: int, a except Exception as e: raise ValueError(f"Failed to predict minting license fee: {str(e)}") - def setLicensingConfig(self, ip_id: str, license_terms_id: int, licensing_config: dict, license_template: str = None, tx_options: dict = None) -> dict: + def set_licensing_config( + self, + ip_id: str, + license_terms_id: int, + licensing_config: dict, + license_template: str = None, + tx_options: dict = 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. @@ -491,9 +544,12 @@ def setLicensingConfig(self, ip_id: str, license_terms_id: int, licensing_config # Check for missing parameters missing_params = required_params - set(licensing_config.keys()) if missing_params: - raise ValueError(f"Missing required licensing_config parameters: {', '.join(missing_params)}. All parameters must be explicitly provided.") + raise ValueError( + f"Missing required licensing_config parameters: {', '.join(missing_params)}. " + f"All parameters must be explicitly provided.") - licensing_config['commercialRevShare'] = self.license_terms_util.get_revenue_share(licensing_config['commercialRevShare']) + licensing_config['commercialRevShare'] = self.license_terms_util.get_revenue_share( + licensing_config['commercialRevShare']) if licensing_config['mintingFee'] < 0: raise ValueError("The minting fee must be greater than 0.") @@ -502,14 +558,17 @@ def setLicensingConfig(self, ip_id: str, license_terms_id: int, licensing_config license_template = ZERO_ADDRESS if license_template == ZERO_ADDRESS and licensing_config['commercialRevShare'] != 0: - raise ValueError("The license template cannot be zero address if commercial revenue share is not zero.") + raise ValueError( + "The license template cannot be zero address if commercial revenue share is not zero.") # Convert addresses to checksum format ip_id = self.web3.to_checksum_address(ip_id) if license_template: license_template = self.web3.to_checksum_address(license_template) - licensing_config['licensingHook'] = self.web3.to_checksum_address(licensing_config['licensingHook']) - licensing_config['expectGroupRewardPool'] = self.web3.to_checksum_address(licensing_config['expectGroupRewardPool']) + licensing_config['licensingHook'] = self.web3.to_checksum_address( + licensing_config['licensingHook']) + licensing_config['expectGroupRewardPool'] = self.web3.to_checksum_address( + licensing_config['expectGroupRewardPool']) # Check if IP is registered if not self.ip_asset_registry_client.isRegistered(ip_id): @@ -539,10 +598,10 @@ def setLicensingConfig(self, ip_id: str, license_terms_id: int, licensing_config ) return { - 'txHash': response['txHash'], - 'success': True if response.get('txReceipt') else None + 'tx_hash': response['tx_hash'], + 'success': True if response.get('tx_receipt') else None } except Exception as e: raise ValueError(f"Failed to set licensing config: {str(e)}") - \ No newline at end of file + 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 2452233..5023129 100644 --- a/src/story_protocol_python_sdk/resources/NFTClient.py +++ b/src/story_protocol_python_sdk/resources/NFTClient.py @@ -6,9 +6,7 @@ from story_protocol_python_sdk.abi.SPGNFTImpl.SPGNFTImpl_client import SPGNFTImplClient from story_protocol_python_sdk.utils.transaction_utils import build_and_send_transaction - -ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" -ZERO_HASH = "0x0000000000000000000000000000000000000000000000000000000000000000" +from story_protocol_python_sdk.utils.constants import ZERO_ADDRESS, ZERO_HASH class NFTClient: """ @@ -25,7 +23,7 @@ def __init__(self, web3: Web3, account, chain_id: int): self.registration_workflows_client = RegistrationWorkflowsClient(web3) - def createNFTCollection(self, name: str, symbol: str, is_public_minting: bool, mint_open: bool, + def create_nft_collection(self, name: str, symbol: str, is_public_minting: bool, mint_open: bool, 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) -> dict: @@ -72,11 +70,11 @@ def createNFTCollection(self, name: str, symbol: str, is_public_minting: bool, m tx_options=tx_options ) - collection_address = self._parse_tx_collection_created_event(response['txReceipt']) + collection_address = self._parse_tx_collection_created_event(response['tx_receipt']) return { - 'txHash': response['txHash'], - 'nftContract': collection_address + 'tx_hash': response['tx_hash'], + 'nft_contract': collection_address } except Exception as e: @@ -97,7 +95,7 @@ def _parse_tx_collection_created_event(self, tx_receipt: dict) -> int: return None - def getMintFeeToken(self, nft_contract: str) -> str: + def get_mint_fee_token(self, nft_contract: str) -> str: """ Returns the current mint fee token of the collection. @@ -112,7 +110,7 @@ def getMintFeeToken(self, nft_contract: str) -> str: except Exception as e: raise ValueError(f"Failed to get mint fee token: {str(e)}") - def getMintFee(self, nft_contract: str) -> int: + def get_mint_fee(self, nft_contract: str) -> int: """ Returns the current mint fee of the collection. diff --git a/src/story_protocol_python_sdk/resources/Royalty.py b/src/story_protocol_python_sdk/resources/Royalty.py index 757f2e5..abe9e94 100644 --- a/src/story_protocol_python_sdk/resources/Royalty.py +++ b/src/story_protocol_python_sdk/resources/Royalty.py @@ -33,7 +33,7 @@ def __init__(self, web3: Web3, account, chain_id: int): self.ip_account_impl_client = IPAccountImplClient(web3) self.mock_erc20_client = MockERC20Client(web3) - def getRoyaltyVaultAddress(self, ip_id: str) -> str: + def get_royalty_vault_address(self, ip_id: str) -> str: """ Get the royalty vault address for a given IP ID. @@ -46,7 +46,7 @@ def getRoyaltyVaultAddress(self, ip_id: str) -> str: return self.royalty_module_client.ipRoyaltyVaults(ip_id) - def claimableRevenue(self, royalty_vault_ip_id: str, claimer: str, token: str) -> int: + def claimable_revenue(self, royalty_vault_ip_id: str, claimer: str, token: str) -> int: """ Calculates the amount of revenue token claimable by a token holder. @@ -56,7 +56,7 @@ def claimableRevenue(self, royalty_vault_ip_id: str, claimer: str, token: str) - :return int: The claimable revenue amount. """ try: - proxy_address = self.getRoyaltyVaultAddress(royalty_vault_ip_id) + proxy_address = self.get_royalty_vault_address(royalty_vault_ip_id) ip_royalty_vault_client = IpRoyaltyVaultImplClient(self.web3, contract_address=proxy_address) claimable_revenue = ip_royalty_vault_client.claimableRevenue( @@ -69,7 +69,7 @@ def claimableRevenue(self, royalty_vault_ip_id: str, claimer: str, token: str) - except Exception as e: raise e - def payRoyaltyOnBehalf(self, receiver_ip_id: str, payer_ip_id: str, token: str, amount: int, tx_options: dict = None) -> dict: + def pay_royalty_on_behalf(self, receiver_ip_id: str, payer_ip_id: str, token: str, amount: int, tx_options: dict = None) -> dict: """ Allows the function caller to pay royalties to the receiver IP asset on behalf of the payer IP asset. @@ -100,12 +100,12 @@ def payRoyaltyOnBehalf(self, receiver_ip_id: str, payer_ip_id: str, token: str, tx_options=tx_options ) - return {'txHash': response['txHash']} + return {'tx_hash': response['tx_hash']} except Exception as e: raise e - def claimAllRevenue(self, ancestor_ip_id: str, claimer: str, child_ip_ids: list, royalty_policies: list, currency_tokens: list, claim_options: dict = None, tx_options: dict = None) -> dict: + def claim_all_revenue(self, ancestor_ip_id: str, claimer: str, child_ip_ids: list, royalty_policies: list, currency_tokens: list, claim_options: dict = None, tx_options: dict = None) -> dict: """ Claims all revenue from the child IPs of an ancestor IP, then optionally transfers and unwraps tokens. @@ -144,27 +144,27 @@ def claimAllRevenue(self, ancestor_ip_id: str, claimer: str, child_ip_ids: list, tx_options=tx_options ) - tx_hashes = [response['txHash']] + tx_hashes = [response['tx_hash']] # Determine if the claimer is an IP owned by the wallet. owns_claimer, is_claimer_ip, ip_account = self._get_claimer_info(claimer) # If wallet does not own the claimer then we cannot auto claim. - # If ownsClaimer is false, it means the claimer is neither an IP owned by the wallet nor the wallet address itself. + # If owns_claimer is false, it means the claimer is neither an IP owned by the wallet nor the wallet address itself. if not owns_claimer: return { - 'receipt': response['txReceipt'], - 'txHashes': tx_hashes + 'receipt': response['tx_receipt'], + 'tx_hashes': tx_hashes } - claimed_tokens = self._parseTxRevenueTokenClaimedEvent(response['txReceipt']) + claimed_tokens = self._parse_tx_revenue_token_claimed_event(response['tx_receipt']) - auto_transfer = claim_options.get('autoTransferAllClaimedTokensFromIp', True) if claim_options else True - # auto_unwrap = claim_options['autoUnwrapIpTokens'] + auto_transfer = claim_options.get('auto_transfer_all_claimed_tokens_from_ip', True) if claim_options else True + # auto_unwrap = claim_options['auto_unwrap_ip_tokens'] # transfer claimed tokens from IP to wallet if wallet owns IP if auto_transfer and is_claimer_ip and owns_claimer: - hashes = self._transferClaimedTokensFromIpToWallet( + hashes = self._transfer_claimed_tokens_from_ip_to_wallet( ancestor_ip_id, ip_account, claimed_tokens @@ -172,9 +172,9 @@ def claimAllRevenue(self, ancestor_ip_id: str, claimer: str, child_ip_ids: list, tx_hashes.extend(hashes) return { - 'receipt': response['txReceipt'], - 'claimedTokens': claimed_tokens, - 'txHashes': tx_hashes + 'receipt': response['tx_receipt'], + 'claimed_tokens': claimed_tokens, + 'tx_hashes': tx_hashes } except Exception as e: @@ -201,7 +201,7 @@ def _get_claimer_info(self, claimer): return owns_claimer, is_claimer_ip, ip_account - def _transferClaimedTokensFromIpToWallet(self, ancestor_ip_id: str, ip_account, claimed_tokens: list) -> list: + def _transfer_claimed_tokens_from_ip_to_wallet(self, ancestor_ip_id: str, ip_account, claimed_tokens: list) -> list: """ Transfer claimed tokens from an IP account to the wallet. @@ -235,11 +235,11 @@ def _transferClaimedTokensFromIpToWallet(self, ancestor_ip_id: str, ip_account, transfer_data, 0 ) - tx_hashes.append(response['txHash']) + tx_hashes.append(response['tx_hash']) return tx_hashes - def _parseTxRevenueTokenClaimedEvent(self, tx_receipt: dict) -> list: + def _parse_tx_revenue_token_claimed_event(self, tx_receipt: dict) -> list: """ Parse the RevenueTokenClaimed events from a transaction receipt. diff --git a/src/story_protocol_python_sdk/resources/WIP.py b/src/story_protocol_python_sdk/resources/WIP.py index 3ca8d58..2b589c6 100644 --- a/src/story_protocol_python_sdk/resources/WIP.py +++ b/src/story_protocol_python_sdk/resources/WIP.py @@ -48,7 +48,7 @@ def deposit(self, amount: int, tx_options: dict = None) -> dict: tx_options=transaction_options ) - return {'txHash': response['txHash']} + return {'tx_hash': response['tx_hash']} except Exception as e: raise ValueError(f"Failed to deposit IP for WIP: {str(e)}") @@ -73,7 +73,7 @@ def withdraw(self, amount: int, tx_options: dict = None) -> dict: tx_options=tx_options ) - return {'txHash': response['txHash']} + return {'tx_hash': response['tx_hash']} except Exception as e: raise ValueError(f"Failed to withdraw WIP: {str(e)}") @@ -105,12 +105,12 @@ def approve(self, spender: str, amount: int, tx_options: dict = None) -> dict: tx_options=tx_options ) - return {'txHash': response['txHash']} + return {'tx_hash': response['tx_hash']} except Exception as e: raise ValueError(f"Failed to approve WIP: {str(e)}") - def balanceOf(self, address: str) -> int: + def balance_of(self, address: str) -> int: """ Returns the balance of WIP for an address. @@ -154,12 +154,12 @@ def transfer(self, to: str, amount: int, tx_options: dict = None) -> dict: tx_options=tx_options ) - return {'txHash': response['txHash']} + return {'tx_hash': response['tx_hash']} except Exception as e: raise ValueError(f"Failed to transfer WIP: {str(e)}") - def transferFrom(self, from_address: str, to: str, amount: int, tx_options: dict = None) -> dict: + def transfer_from(self, from_address: str, to: str, amount: int, tx_options: dict = None) -> dict: """ Transfers `amount` of WIP from `from_address` to a recipient `to`. @@ -192,7 +192,7 @@ def transferFrom(self, from_address: str, to: str, amount: int, tx_options: dict tx_options=tx_options ) - return {'txHash': response['txHash']} + return {'tx_hash': response['tx_hash']} except Exception as e: raise ValueError(f"Failed to transfer WIP from another address: {str(e)}") diff --git a/src/story_protocol_python_sdk/scripts/generate_clients.py b/src/story_protocol_python_sdk/scripts/generate_clients.py index 2742be0..39b2d84 100644 --- a/src/story_protocol_python_sdk/scripts/generate_clients.py +++ b/src/story_protocol_python_sdk/scripts/generate_clients.py @@ -30,13 +30,13 @@ def __init__(self, web3: Web3): abi = json.load(abi_file) self.contract = self.web3.eth.contract(address=contract_address, abi=abi) {% for function in functions %} - def {{ function.name }}(self, {% if function.inputs %}{{ function.inputs | join(', ') }}{% endif %}): + def {{ function.python_name }}(self{% if function.inputs %}, {{ function.inputs | join(', ') }}{% endif %}): {% if function.stateMutability == 'view' or function.stateMutability == 'pure' %} return self.contract.functions.{{ function.name }}({% if function.inputs %}{{ function.inputs | join(', ') }}{% endif %}).call() {% else %} return self.contract.functions.{{ function.name }}({% if function.inputs %}{{ function.inputs | join(', ') }}{% endif %}).transact() - def build_{{ function.name }}_transaction(self, {% if function.inputs %}{{ function.inputs | join(', ') }}, {% endif %}tx_params): + def build_{{ function.python_name }}_transaction(self{% if function.inputs %}, {{ function.inputs | join(', ') }}{% endif %}, tx_params): return self.contract.functions.{{ function.name }}({% if function.inputs %}{{ function.inputs | join(', ') }}{% endif %}).build_transaction(tx_params) {% endif %} {% endfor %} @@ -56,13 +56,13 @@ def __init__(self, web3: Web3, contract_address=None): abi = json.load(abi_file) self.contract = self.web3.eth.contract(address=contract_address, abi=abi) {% for function in functions %} - def {{ function.name }}(self, {% if function.inputs %}{{ function.inputs | join(', ') }}{% endif %}): + def {{ function.python_name }}(self{% if function.inputs %}, {{ function.inputs | join(', ') }}{% endif %}): {% if function.stateMutability == 'view' or function.stateMutability == 'pure' %} return self.contract.functions.{{ function.name }}({% if function.inputs %}{{ function.inputs | join(', ') }}{% endif %}).call() {% else %} return self.contract.functions.{{ function.name }}({% if function.inputs %}{{ function.inputs | join(', ') }}{% endif %}).transact() - def build_{{ function.name }}_transaction(self, {% if function.inputs %}{{ function.inputs | join(', ') }}, {% endif %}tx_params): + def build_{{ function.python_name }}_transaction(self{% if function.inputs %}, {{ function.inputs | join(', ') }}{% endif %}, tx_params): return self.contract.functions.{{ function.name }}({% if function.inputs %}{{ function.inputs | join(', ') }}{% endif %}).build_transaction(tx_params) {% endif %} {% endfor %} @@ -81,8 +81,16 @@ def generate_python_class_from_abi(abi, contract_name, functions, output_dir): class_name = contract_name + 'Client' selected_functions = [] + function_name_counts = {} + for item in abi: if item['type'] == 'function' and item['name'] in functions: + # Count occurrences of function names + if item['name'] in function_name_counts: + function_name_counts[item['name']] += 1 + else: + function_name_counts[item['name']] = 1 + function = { 'name': item['name'], 'inputs': [input['name'] for input in item['inputs']], @@ -90,6 +98,17 @@ def generate_python_class_from_abi(abi, contract_name, functions, output_dir): } selected_functions.append(function) + # Add python_name to each function, with numbering for duplicates + function_name_seen = {} + for function in selected_functions: + name = function['name'] + if name in function_name_seen: + function_name_seen[name] += 1 + function['python_name'] = f"{name}{function_name_seen[name] + 1}" + else: + function_name_seen[name] = 0 + function['python_name'] = name + # Sort functions: transact functions first, call functions later selected_functions.sort(key=lambda x: x['stateMutability'] in ['view', 'pure']) @@ -112,6 +131,37 @@ def generate_python_class_from_abi(abi, contract_name, functions, output_dir): print(f"Generated {class_name} class from ABI") +def fix_client_formatting(client_dir): + """Fix formatting issues in generated client files.""" + for root, dirs, files in os.walk(client_dir): + for file in files: + if file.endswith('_client.py'): + file_path = os.path.join(root, file) + with open(file_path, 'r') as f: + content = f.read() + + # Fix empty lines between functions (ensure exactly one empty line) + import re + # Replace multiple empty lines between function definitions with a single empty line + content = re.sub(r'(\n def [^\n]+\n)(\s*\n)+(\s+def)', r'\1\n\3', content) + + # Remove empty lines within function bodies + content = re.sub(r'(\n [^\n]+\n)(\s*\n)(\s{8})', r'\1\3', content) + + # Fix parameter formatting for functions with only 'self' + content = re.sub(r'def ([a-zA-Z0-9_]+)\(self, \):', r'def \1(self):', content) + + # Fix empty lines in view/pure function bodies - specifically target the empty line between function definition and return statement + content = re.sub(r'(def [a-zA-Z0-9_]+\(self(?:, [^\)]+)?\):\n\s*\n)(\s+return)', r'\1\2', content) + + # Remove empty lines between function definition and return statement for all functions + content = re.sub(r'(def [a-zA-Z0-9_]+\(self(?:, [^\)]+)?\):\n)\s*\n(\s+return)', r'\1\2', content) + + with open(file_path, 'w') as f: + f.write(content) + + # print(f"Fixed formatting for {file_path}") + def main(config_path, output_dir): """Main function to generate client classes from ABIs.""" with open(config_path, 'r') as config_file: @@ -125,6 +175,9 @@ def main(config_path, output_dir): generate_python_class_from_abi(abi, contract_name, functions, output_dir) except Exception as e: print(f"Error generating class for {contract_name}: {e}") + + # Fix formatting in all generated client files + fix_client_formatting(output_dir) if __name__ == "__main__": config_path = os.path.join(os.path.dirname(__file__), 'config.json') diff --git a/src/story_protocol_python_sdk/story_client.py b/src/story_protocol_python_sdk/story_client.py index c322566..e66adf9 100644 --- a/src/story_protocol_python_sdk/story_client.py +++ b/src/story_protocol_python_sdk/story_client.py @@ -142,7 +142,7 @@ def WIP(self) -> WIP: self._wip = WIP(self.web3, self.account, self.chain_id) return self._wip - def getWalletBalance(self) -> int: + def get_wallet_balance(self) -> int: """ Get the WIP token balance of the current wallet. diff --git a/src/story_protocol_python_sdk/utils/constants.py b/src/story_protocol_python_sdk/utils/constants.py new file mode 100644 index 0000000..df83925 --- /dev/null +++ b/src/story_protocol_python_sdk/utils/constants.py @@ -0,0 +1,4 @@ +ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" +ZERO_HASH = "0x0000000000000000000000000000000000000000000000000000000000000000" +ROYALTY_POLICY = "0xBe54FB168b3c982b7AaE60dB6CF75Bd8447b390E" +ZERO_FUNC = "0x00000000" diff --git a/src/story_protocol_python_sdk/utils/license_terms.py b/src/story_protocol_python_sdk/utils/license_terms.py index 6936aba..6404c6a 100644 --- a/src/story_protocol_python_sdk/utils/license_terms.py +++ b/src/story_protocol_python_sdk/utils/license_terms.py @@ -3,9 +3,7 @@ from web3 import Web3 from story_protocol_python_sdk.abi.RoyaltyModule.RoyaltyModule_client import RoyaltyModuleClient - -ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" -ROYALTY_POLICY = "0xBe54FB168b3c982b7AaE60dB6CF75Bd8447b390E" +from story_protocol_python_sdk.utils.constants import ZERO_ADDRESS, ROYALTY_POLICY class LicenseTerms: def __init__(self, web3: Web3): diff --git a/src/story_protocol_python_sdk/utils/sign.py b/src/story_protocol_python_sdk/utils/sign.py index 00d538a..e3018cd 100644 --- a/src/story_protocol_python_sdk/utils/sign.py +++ b/src/story_protocol_python_sdk/utils/sign.py @@ -9,8 +9,7 @@ from story_protocol_python_sdk.abi.IPAccountImpl.IPAccountImpl_client import IPAccountImplClient from story_protocol_python_sdk.abi.AccessController.AccessController_client import AccessControllerClient -ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" -ZERO_FUNC = "0x00000000" +from story_protocol_python_sdk.utils.constants import ZERO_FUNC class Sign: def __init__(self, web3: Web3, chain_id: int, account): diff --git a/src/story_protocol_python_sdk/utils/transaction_utils.py b/src/story_protocol_python_sdk/utils/transaction_utils.py index f9b075d..deeaa7f 100644 --- a/src/story_protocol_python_sdk/utils/transaction_utils.py +++ b/src/story_protocol_python_sdk/utils/transaction_utils.py @@ -47,8 +47,8 @@ def build_and_send_transaction(web3: Web3, account, client_function, *client_arg tx_receipt = web3.eth.wait_for_transaction_receipt(tx_hash, timeout=TRANSACTION_TIMEOUT) return { - 'txHash': tx_hash.hex(), - 'txReceipt': tx_receipt + 'tx_hash': tx_hash.hex(), + 'tx_receipt': tx_receipt } except Exception as e: diff --git a/tests/integration/setup_for_integration.py b/tests/integration/setup_for_integration.py index ce49301..cc075c3 100644 --- a/tests/integration/setup_for_integration.py +++ b/tests/integration/setup_for_integration.py @@ -16,7 +16,7 @@ get_token_id, mint_tokens, approve, - getBlockTimestamp, + get_block_timestamp, check_event_in_tx, MockERC721, MockERC20, @@ -69,7 +69,7 @@ def story_client_2(): 'get_token_id', 'mint_tokens', 'approve', - 'getBlockTimestamp', + 'get_block_timestamp', 'check_event_in_tx', 'MockERC721', 'MockERC20', diff --git a/tests/integration/test_integration_dispute.py b/tests/integration/test_integration_dispute.py index bd58b5d..98a4ea4 100644 --- a/tests/integration/test_integration_dispute.py +++ b/tests/integration/test_integration_dispute.py @@ -1,5 +1,6 @@ +# tests/integration/test_integration_dispute.py + import pytest -import time from web3 import Web3 from setup_for_integration import ( @@ -17,18 +18,17 @@ class TestDispute: @pytest.fixture(scope="module") def target_ip_id(self, story_client, story_client_2): """Create an IP to be disputed""" - txData = story_client.NFTClient.createNFTCollection( + txData = story_client.NFTClient.create_nft_collection( name="test-collection", symbol="TEST", max_supply=100, is_public_minting=True, mint_open=True, contract_uri="test-uri", - mint_fee_recipient=account.address, - tx_options={ "wait_for_transaction": True} + mint_fee_recipient=account.address ) - nft_contract = txData['nftContract'] + nft_contract = txData['nft_contract'] metadata_a = { 'ip_metadata_uri': "test-uri-a", @@ -37,13 +37,13 @@ def target_ip_id(self, story_client, story_client_2): 'nft_metadata_hash': web3.to_hex(web3.keccak(text="test-nft-metadata-hash-a")) } - response = story_client_2.IPAsset.mintAndRegisterIp( + response = story_client_2.IPAsset.mint_and_register_ip( spg_nft_contract=nft_contract, ip_metadata=metadata_a, tx_options={ "wait_for_transaction": True} ) - return response['ipId'] + return response['ip_id'] def test_raise_dispute(self, story_client, target_ip_id): """Test raising a dispute""" @@ -59,7 +59,7 @@ def test_raise_dispute(self, story_client, target_ip_id): # amount=2**256 - 1 # maximum uint256 value # ) - response = story_client.Dispute.raiseDispute( + response = story_client.Dispute.raise_dispute( target_ip_id=target_ip_id, target_tag="IMPROPER_REGISTRATION", cid=cid, @@ -67,9 +67,9 @@ def test_raise_dispute(self, story_client, target_ip_id): bond=bond_amount ) - assert 'txHash' in response - assert isinstance(response['txHash'], str) - assert len(response['txHash']) > 0 - assert 'disputeId' in response - assert isinstance(response['disputeId'], int) - assert response['disputeId'] > 0 + assert 'tx_hash' in response + assert isinstance(response['tx_hash'], str) + assert len(response['tx_hash']) > 0 + assert 'dispute_id' in response + assert isinstance(response['dispute_id'], int) + assert response['dispute_id'] > 0 diff --git a/tests/integration/test_integration_ip_account.py b/tests/integration/test_integration_ip_account.py index c7dbfe4..4e190e9 100644 --- a/tests/integration/test_integration_ip_account.py +++ b/tests/integration/test_integration_ip_account.py @@ -12,7 +12,7 @@ story_client, get_token_id, mint_tokens, - getBlockTimestamp, + get_block_timestamp, MockERC721, MockERC20, private_key @@ -30,7 +30,7 @@ def test_execute(self, story_client): data = story_client.IPAccount.access_controller_client.contract.encode_abi( abi_element_identifier="setTransientPermission", - args=[response['ipId'], + args=[response['ip_id'], account.address, "0x89630Ccf23277417FBdfd3076C702F5248267e78", Web3.keccak(text="function setAll(address,string,bytes32,bytes32)")[:4], @@ -40,15 +40,15 @@ def test_execute(self, story_client): response = story_client.IPAccount.execute( to=story_client.IPAccount.access_controller_client.contract.address, value=0, - ip_id=response['ipId'], + ip_id=response['ip_id'], data=data ) assert response is not None, "Response is None, indicating the contract interaction failed." - assert 'txHash' in response, "Response does not contain 'txHash'." - assert response['txHash'] is not None, "'txHash' is None." - assert isinstance(response['txHash'], str), "'txHash' is not a string." - assert len(response['txHash']) > 0, "'txHash' is empty." + assert 'tx_hash' in response, "Response does not contain 'tx_hash'." + assert response['tx_hash'] is not None, "'tx_hash' is None." + assert isinstance(response['tx_hash'], str), "'tx_hash' is not a string." + assert len(response['tx_hash']) > 0, "'tx_hash' is empty." def test_get_ip_account_nonce(self, story_client): """Test getting IP Account nonce.""" @@ -57,9 +57,9 @@ def test_get_ip_account_nonce(self, story_client): nft_contract=MockERC721, token_id=token_id ) - ip_id = register_response['ipId'] + ip_id = register_response['ip_id'] - state = story_client.IPAccount.getIpAccountNonce(ip_id) + state = story_client.IPAccount.get_ip_account_nonce(ip_id) assert state is not None assert isinstance(state, bytes) @@ -71,7 +71,7 @@ def test_execute_with_encoded_data(self, story_client): nft_contract=MockERC721, token_id=token_id ) - ip_id = register_response['ipId'] + ip_id = register_response['ip_id'] data = story_client.IPAccount.access_controller_client.contract.encode_abi( abi_element_identifier="setTransientPermission", @@ -92,23 +92,23 @@ def test_execute_with_encoded_data(self, story_client): ) assert response is not None - assert 'txHash' in response - assert isinstance(response['txHash'], str) - assert len(response['txHash']) > 0 + assert 'tx_hash' in response + assert isinstance(response['tx_hash'], str) + assert len(response['tx_hash']) > 0 class TestSignatureOperations: """Tests for operations involving signatures""" - def test_executeWithSig(self, story_client): + def test_execute_with_sig(self, story_client): token_id = get_token_id(MockERC721, story_client.web3, story_client.account) response = story_client.IPAsset.register( nft_contract=MockERC721, token_id=token_id ) - ip_id = response['ipId'] - deadline = getBlockTimestamp(web3) + 100 - state = story_client.IPAccount.getIpAccountNonce(ip_id) + ip_id = response['ip_id'] + deadline = get_block_timestamp(web3) + 100 + state = story_client.IPAccount.get_ip_account_nonce(ip_id) core_data = story_client.IPAccount.access_controller_client.contract.encode_abi( abi_element_identifier="setTransientPermission", @@ -165,7 +165,7 @@ def test_executeWithSig(self, story_client): signable_message = encode_typed_data(domain_data, message_types, message_data) signed_message = Account.sign_message(signable_message, private_key) - response = story_client.IPAccount.executeWithSig( + response = story_client.IPAccount.execute_with_sig( to=story_client.IPAccount.access_controller_client.contract.address, value=0, ip_id=ip_id, @@ -176,9 +176,9 @@ def test_executeWithSig(self, story_client): ) assert response is not None - assert 'txHash' in response - assert isinstance(response['txHash'], str) - assert len(response['txHash']) > 0 + assert 'tx_hash' in response + assert isinstance(response['tx_hash'], str) + assert len(response['tx_hash']) > 0 def test_execute_with_sig_multiple_permissions(self, story_client): """Test executeWithSig setting multiple permissions.""" @@ -187,10 +187,10 @@ def test_execute_with_sig_multiple_permissions(self, story_client): nft_contract=MockERC721, token_id=token_id ) - ip_id = register_response['ipId'] + ip_id = register_response['ip_id'] - deadline = getBlockTimestamp(web3) + 100 - state = story_client.IPAccount.getIpAccountNonce(ip_id) + deadline = get_block_timestamp(web3) + 100 + state = story_client.IPAccount.get_ip_account_nonce(ip_id) # Prepare all function signatures for permissions function_signatures = [ @@ -264,7 +264,7 @@ def test_execute_with_sig_multiple_permissions(self, story_client): signable_message = encode_typed_data(domain_data, message_types, message_data) signed_message = Account.sign_message(signable_message, private_key) - response = story_client.IPAccount.executeWithSig( + response = story_client.IPAccount.execute_with_sig( ip_id=ip_id, to=story_client.IPAccount.access_controller_client.contract.address, value=0, @@ -275,9 +275,9 @@ def test_execute_with_sig_multiple_permissions(self, story_client): ) assert response is not None - assert 'txHash' in response - assert isinstance(response['txHash'], str) - assert len(response['txHash']) > 0 + assert 'tx_hash' in response + assert isinstance(response['tx_hash'], str) + assert len(response['tx_hash']) > 0 class TestErrorCases: """Tests for error cases and validation""" @@ -289,7 +289,7 @@ def test_execute_invalid_address(self, story_client): nft_contract=MockERC721, token_id=token_id ) - ip_id = register_response['ipId'] + ip_id = register_response['ip_id'] data = "0x" invalid_address = "0xinvalid" @@ -319,6 +319,78 @@ def test_execute_unregistered_ip(self, story_client): assert "is not registered" in str(exc_info.value) + def test_execute_with_sig_wrong_signer(self, story_client): + """Test executeWithSig with a valid signature but wrong signer address.""" + token_id = get_token_id(MockERC721, story_client.web3, story_client.account) + register_response = story_client.IPAsset.register( + nft_contract=MockERC721, + token_id=token_id + ) + ip_id = register_response['ip_id'] + + deadline = get_block_timestamp(web3) + 100 + state = story_client.IPAccount.get_ip_account_nonce(ip_id) + data = "0x" + + execute_data = story_client.IPAccount.ip_account_client.contract.encode_abi( + abi_element_identifier="execute", + args=[ + story_client.IPAccount.access_controller_client.contract.address, + 0, + data + ] + ) + + expected_state = Web3.keccak( + encode( + ["bytes32", "bytes"], + [state, Web3.to_bytes(hexstr=execute_data)] + ) + ) + + domain_data = { + "name": "Story Protocol IP Account", + "version": "1", + "chainId": 1315, + "verifyingContract": ip_id, + } + + message_types = { + "Execute": [ + {"name": "to", "type": "address"}, + {"name": "value", "type": "uint256"}, + {"name": "data", "type": "bytes"}, + {"name": "nonce", "type": "bytes32"}, + {"name": "deadline", "type": "uint256"}, + ], + } + + message_data = { + "to": story_client.IPAccount.access_controller_client.contract.address, + "value": 0, + "data": data, + "nonce": expected_state, + "deadline": deadline, + } + + signable_message = encode_typed_data(domain_data, message_types, message_data) + signed_message = Account.sign_message(signable_message, private_key) + wrong_signer = "0x1234567890123456789012345678901234567890" + + with pytest.raises(Exception) as exc_info: + story_client.IPAccount.execute_with_sig( + ip_id=ip_id, + to=story_client.IPAccount.access_controller_client.contract.address, + value=0, + data=data, + signer=wrong_signer, # Wrong signer address + deadline=deadline, + signature=signed_message.signature + ) + + error_hex = '0x3fd60002' + assert error_hex in str(exc_info.value), f"Expected error code {error_hex} for wrong signer" + class TestSetIpMetadata: """Tests for setting IP metadata""" @@ -329,17 +401,17 @@ def test_set_ip_metadata(self, story_client): token_id=token_id ) - response = story_client.IPAccount.setIpMetadata( - ip_id=response['ipId'], + response = story_client.IPAccount.set_ip_metadata( + ip_id=response['ip_id'], metadata_uri="https://example.com", metadata_hash=web3.to_hex(web3.keccak(text="test-metadata-hash")) ) assert response is not None, "Response is None, indicating the contract interaction failed." - assert 'txHash' in response, "Response does not contain 'txHash'." - assert response['txHash'] is not None, "'txHash' is None." - assert isinstance(response['txHash'], str), "'txHash' is not a string." - assert len(response['txHash']) > 0, "'txHash' is empty." + assert 'tx_hash' in response, "Response does not contain 'tx_hash'." + assert response['tx_hash'] is not None, "'tx_hash' is None." + assert isinstance(response['tx_hash'], str), "'tx_hash' is not a string." + assert len(response['tx_hash']) > 0, "'tx_hash' is empty." def test_execute_with_sig_wrong_signer(self, story_client): """Test executeWithSig with a valid signature but wrong signer address.""" @@ -409,10 +481,6 @@ def test_execute_with_sig_wrong_signer(self, story_client): deadline=deadline, signature=signed_message.signature ) - - print(f"Exception type: {type(exc_info.value)}") - print(f"Exception value: {exc_info.value}") - print(f"Exception args: {exc_info.value.args if hasattr(exc_info.value, 'args') else 'No args'}") error_hex = '0x3fd60002' assert error_hex in str(exc_info.value), f"Expected error code {error_hex} for wrong signer" @@ -467,7 +535,7 @@ def test_transfer_erc20(self, story_client): nft_contract=MockERC721, token_id=token_id ) - ip_id = response['ipId'] + ip_id = response['ip_id'] # 1. Query token balance of ip_id and wallet before initial_erc20_balance_of_ip_id = story_client.Royalty.mock_erc20_client.balanceOf( @@ -476,10 +544,10 @@ def test_transfer_erc20(self, story_client): initial_erc20_balance_of_wallet = story_client.Royalty.mock_erc20_client.balanceOf( account=story_client.account.address ) - initial_wip_balance_of_ip_id = story_client.WIP.balanceOf( + initial_wip_balance_of_ip_id = story_client.WIP.balance_of( address=ip_id ) - initial_wip_balance_of_wallet = story_client.WIP.balanceOf( + initial_wip_balance_of_wallet = story_client.WIP.balance_of( address=story_client.account.address ) @@ -506,7 +574,7 @@ def test_transfer_erc20(self, story_client): ) # 4. Transfer tokens from IP account to wallet address - response = story_client.IPAccount.transferERC20( + response = story_client.IPAccount.transfer_erc20( ip_id=ip_id, tokens=[ { @@ -531,18 +599,58 @@ def test_transfer_erc20(self, story_client): final_erc20_balance_of_ip_id = story_client.Royalty.mock_erc20_client.balanceOf( account=ip_id ) - final_wip_balance_of_ip_id = story_client.WIP.balanceOf( + final_wip_balance_of_ip_id = story_client.WIP.balance_of( address=ip_id ) final_erc20_balance_of_wallet = story_client.Royalty.mock_erc20_client.balanceOf( account=story_client.account.address ) - final_wip_balance_of_wallet = story_client.WIP.balanceOf( + final_wip_balance_of_wallet = story_client.WIP.balance_of( address=story_client.account.address ) - assert isinstance(response['txHash'], str) and response['txHash'] != "" + assert isinstance(response['tx_hash'], str) and response['tx_hash'] != "" assert final_erc20_balance_of_ip_id == initial_erc20_balance_of_ip_id assert final_wip_balance_of_ip_id == initial_wip_balance_of_ip_id assert final_erc20_balance_of_wallet == initial_erc20_balance_of_wallet + 2000000 assert final_wip_balance_of_wallet == initial_wip_balance_of_wallet + 1 + + @pytest.mark.skip(reason="contract allows empty calls") + def test_transfer_erc20_empty_tokens(self, story_client): + """Test transferERC20 with empty tokens list.""" + token_id = get_token_id(MockERC721, story_client.web3, story_client.account) + register_response = story_client.IPAsset.register( + nft_contract=MockERC721, + token_id=token_id + ) + ip_id = register_response['ip_id'] + + # Try to transfer with empty tokens list + with pytest.raises(Exception) as exc_info: + story_client.IPAccount.transfer_erc20( + ip_id=ip_id, + tokens=[] # Empty tokens list + ) + + def test_transfer_erc20_invalid_token_params(self, story_client): + """Test transferERC20 with invalid token parameters.""" + token_id = get_token_id(MockERC721, story_client.web3, story_client.account) + register_response = story_client.IPAsset.register( + nft_contract=MockERC721, + token_id=token_id + ) + ip_id = register_response['ip_id'] + + with pytest.raises(ValueError) as exc_info: + story_client.IPAccount.transfer_erc20( + ip_id=ip_id, + tokens=[ + { + # Missing 'address' + "target": story_client.account.address, + "amount": 1000000 + } + ] + ) + assert "must include" in str(exc_info.value), "Error should mention missing parameter" + \ No newline at end of file diff --git a/tests/integration/test_integration_ip_asset.py b/tests/integration/test_integration_ip_asset.py index 084b9fe..9599782 100644 --- a/tests/integration/test_integration_ip_asset.py +++ b/tests/integration/test_integration_ip_asset.py @@ -1,7 +1,6 @@ -import os -import sys +# tests/integration/test_integration_ip_asset.py + import pytest -from dotenv import load_dotenv from web3 import Web3 from setup_for_integration import ( @@ -9,15 +8,10 @@ account, story_client, get_token_id, - mint_tokens, - approve, - getBlockTimestamp, - check_event_in_tx, MockERC721, MockERC20, ZERO_ADDRESS, ROYALTY_POLICY, - ROYALTY_MODULE, PIL_LICENSE_TEMPLATE ) @@ -31,13 +25,13 @@ def child_ip_id(self, story_client): token_id=token_id ) - assert 'txHash' in response - assert isinstance(response['txHash'], str) + assert 'tx_hash' in response + assert isinstance(response['tx_hash'], str) assert response is not None - assert 'ipId' in response - assert response['ipId'] is not None - return response['ipId'] + assert 'ip_id' in response + assert response['ip_id'] is not None + return response['ip_id'] def test_register_ip_asset(self, story_client, child_ip_id): assert child_ip_id is not None @@ -58,13 +52,13 @@ def test_register_ip_asset_with_metadata(self, story_client): deadline=1000 ) - assert 'txHash' in response - assert isinstance(response['txHash'], str) + assert 'tx_hash' in response + assert isinstance(response['tx_hash'], str) assert response is not None - assert 'ipId' in response - assert response['ipId'] is not None - assert isinstance(response['ipId'], str) + assert 'ip_id' in response + assert response['ip_id'] is not None + assert isinstance(response['ip_id'], str) class TestIPAssetDerivatives: @pytest.fixture(scope="module") @@ -76,18 +70,18 @@ def child_ip_id(self, story_client): token_id=token_id ) - assert 'txHash' in response - assert isinstance(response['txHash'], str) + assert 'tx_hash' in response + assert isinstance(response['tx_hash'], str) assert response is not None - assert 'ipId' in response - assert response['ipId'] is not None - return response['ipId'] + assert 'ip_id' in response + assert response['ip_id'] is not None + return response['ip_id'] @pytest.fixture(scope="module") def non_commercial_license(self, story_client): - license_register_response = story_client.License.registerNonComSocialRemixingPIL() - no_commercial_license_terms_id = license_register_response['licenseTermsId'] + license_register_response = story_client.License.register_non_com_social_remixing_pil() + no_commercial_license_terms_id = license_register_response['license_terms_id'] return no_commercial_license_terms_id @pytest.fixture(scope="module") @@ -98,12 +92,12 @@ def parent_ip_id(self, story_client, non_commercial_license): token_id=token_id ) - attach_license_response = story_client.License.attachLicenseTerms(response['ipId'], PIL_LICENSE_TEMPLATE, non_commercial_license) + attach_license_response = story_client.License.attach_license_terms(response['ip_id'], PIL_LICENSE_TEMPLATE, non_commercial_license) - return response['ipId'] + return response['ip_id'] def test_register_derivative(self, story_client, child_ip_id, parent_ip_id, non_commercial_license): - response = story_client.IPAsset.registerDerivative( + response = story_client.IPAsset.register_derivative( child_ip_id=child_ip_id, parent_ip_ids=[parent_ip_id], license_terms_ids=[non_commercial_license], @@ -113,20 +107,20 @@ def test_register_derivative(self, story_client, child_ip_id, parent_ip_id, non_ ) assert response is not None - assert 'txHash' in response - assert response['txHash'] is not None - assert isinstance(response['txHash'], str) - assert len(response['txHash']) > 0 + assert 'tx_hash' in response + assert response['tx_hash'] is not None + assert isinstance(response['tx_hash'], str) + assert len(response['tx_hash']) > 0 - def test_registerDerivativeWithLicenseTokens(self, story_client, parent_ip_id, non_commercial_license): + def test_register_derivative_with_license_tokens(self, story_client, parent_ip_id, non_commercial_license): token_id = get_token_id(MockERC721, story_client.web3, story_client.account) child_response = story_client.IPAsset.register( nft_contract=MockERC721, token_id=token_id ) - child_ip_id = child_response['ipId'] + child_ip_id = child_response['ip_id'] - license_token_response = story_client.License.mintLicenseTokens( + license_token_response = story_client.License.mint_license_tokens( licensor_ip_id=parent_ip_id, license_template=PIL_LICENSE_TEMPLATE, license_terms_id=non_commercial_license, @@ -135,24 +129,24 @@ def test_registerDerivativeWithLicenseTokens(self, story_client, parent_ip_id, n max_minting_fee=0, max_revenue_share=1 ) - licenseTokenIds = license_token_response['licenseTokenIds'] + license_token_ids = license_token_response['license_token_ids'] - response = story_client.IPAsset.registerDerivativeWithLicenseTokens( + response = story_client.IPAsset.register_derivative_with_license_tokens( child_ip_id=child_ip_id, - license_token_ids=licenseTokenIds, + license_token_ids=license_token_ids, max_rts=5 * 10 ** 6 ) assert response is not None - assert 'txHash' in response - assert response['txHash'] is not None - assert isinstance(response['txHash'], str) - assert len(response['txHash']) > 0 + assert 'tx_hash' in response + assert response['tx_hash'] is not None + assert isinstance(response['tx_hash'], str) + assert len(response['tx_hash']) > 0 class TestIPAssetMinting: @pytest.fixture(scope="module") def nft_collection(self, story_client): - txData = story_client.NFTClient.createNFTCollection( + tx_data = story_client.NFTClient.create_nft_collection( name="test-collection", symbol="TEST", max_supply=100, @@ -161,7 +155,7 @@ def nft_collection(self, story_client): contract_uri="test-uri", mint_fee_recipient=account.address, ) - return txData['nftContract'] + return tx_data['nft_contract'] def test_mint_register_attach_terms(self, story_client, nft_collection): metadata = { @@ -171,7 +165,7 @@ def test_mint_register_attach_terms(self, story_client, nft_collection): 'nft_metadata_hash': web3.to_hex(web3.keccak(text="test-nft-metadata-hash")) } - response = story_client.IPAsset.mintAndRegisterIpAssetWithPilTerms( + response = story_client.IPAsset.mint_and_register_ip_asset_with_pil_terms( spg_nft_contract=nft_collection, terms=[{ 'terms': { @@ -207,19 +201,19 @@ def test_mint_register_attach_terms(self, story_client, nft_collection): ip_metadata=metadata ) - assert 'txHash' in response - assert isinstance(response['txHash'], str) + assert 'tx_hash' in response + assert isinstance(response['tx_hash'], str) - assert 'ipId' in response - assert isinstance(response['ipId'], str) - assert response['ipId'].startswith("0x") + assert 'ip_id' in response + assert isinstance(response['ip_id'], str) + assert response['ip_id'].startswith("0x") - assert 'tokenId' in response - assert isinstance(response['tokenId'], int) + assert 'token_id' in response + assert isinstance(response['token_id'], int) - assert 'licenseTermsIds' in response - assert isinstance(response['licenseTermsIds'], list) - assert all(isinstance(id, int) for id in response['licenseTermsIds']) + assert 'license_terms_ids' in response + assert isinstance(response['license_terms_ids'], list) + assert all(isinstance(id, int) for id in response['license_terms_ids']) def test_mint_register_ip(self, story_client, nft_collection): metadata = { @@ -229,7 +223,7 @@ def test_mint_register_ip(self, story_client, nft_collection): 'nft_metadata_hash': web3.to_hex(web3.keccak(text="test-nft-metadata-hash")) } - response = story_client.IPAsset.mintAndRegisterIp( + response = story_client.IPAsset.mint_and_register_ip( spg_nft_contract=nft_collection, ip_metadata=metadata ) diff --git a/tests/integration/test_integration_license.py b/tests/integration/test_integration_license.py index a2837af..935c56c 100644 --- a/tests/integration/test_integration_license.py +++ b/tests/integration/test_integration_license.py @@ -1,9 +1,6 @@ # tests/integration/test_integration_license.py -import os -import sys import pytest -from dotenv import load_dotenv from web3 import Web3 from setup_for_integration import ( @@ -13,8 +10,6 @@ get_token_id, mint_tokens, approve, - getBlockTimestamp, - check_event_in_tx, MockERC721, MockERC20, ZERO_ADDRESS, @@ -23,8 +18,8 @@ PIL_LICENSE_TEMPLATE ) -def test_registerPILTerms(story_client): - response = story_client.License.registerPILTerms( +def test_register_pil_terms(story_client): + response = story_client.License.register_pil_terms( transferable=False, royalty_policy=story_client.web3.to_checksum_address("0x0000000000000000000000000000000000000000"), default_minting_fee=0, @@ -45,39 +40,39 @@ def test_registerPILTerms(story_client): ) assert response is not None - assert 'licenseTermsId' in response - assert response['licenseTermsId'] is not None - assert isinstance(response['licenseTermsId'], int) + assert 'license_terms_id' in response + assert response['license_terms_id'] is not None + assert isinstance(response['license_terms_id'], int) -def test_registerNonComSocialRemixingPIL(story_client): - response = story_client.License.registerNonComSocialRemixingPIL() +def test_register_non_com_social_remixing_pil(story_client): + response = story_client.License.register_non_com_social_remixing_pil() assert response is not None - assert 'licenseTermsId' in response - assert response['licenseTermsId'] is not None - assert isinstance(response['licenseTermsId'], int) + assert 'license_terms_id' in response + assert response['license_terms_id'] is not None + assert isinstance(response['license_terms_id'], int) @pytest.fixture(scope="module") -def registerCommercialUsePIL(story_client): - response = story_client.License.registerCommercialUsePIL( +def register_commercial_use_pil(story_client): + response = story_client.License.register_commercial_use_pil( default_minting_fee=11, currency=MockERC20, royalty_policy=ROYALTY_POLICY ) assert response is not None, "Response is None, indicating the contract interaction failed." - assert 'licenseTermsId' in response, "Response does not contain 'licenseTermsId'." - assert response['licenseTermsId'] is not None, "'licenseTermsId' is None." - assert isinstance(response['licenseTermsId'], int), "'licenseTermsId' is not an integer." + assert 'license_terms_id' in response, "Response does not contain 'license_terms_id'." + assert response['license_terms_id'] is not None, "'license_terms_id' is None." + assert isinstance(response['license_terms_id'], int), "'license_terms_id' is not an integer." - return response['licenseTermsId'] + return response['license_terms_id'] -def test_registerCommercialUsePIL(story_client, registerCommercialUsePIL): - assert registerCommercialUsePIL is not None +def test_register_commercial_use_pil(story_client, register_commercial_use_pil): + assert register_commercial_use_pil is not None @pytest.fixture(scope="module") -def registerCommercialRemixPIL(story_client): - response = story_client.License.registerCommercialRemixPIL( +def register_commercial_remix_pil(story_client): + response = story_client.License.register_commercial_remix_pil( default_minting_fee=1, currency=MockERC20, commercial_rev_share=100, @@ -85,14 +80,14 @@ def registerCommercialRemixPIL(story_client): ) assert response is not None, "Response is None, indicating the contract interaction failed." - assert 'licenseTermsId' in response, "Response does not contain 'licenseTermsId'." - assert response['licenseTermsId'] is not None, "'licenseTermsId' is None." - assert isinstance(response['licenseTermsId'], int), "'licenseTermsId' is not an integer." + assert 'license_terms_id' in response, "Response does not contain 'license_terms_id'." + assert response['license_terms_id'] is not None, "'license_terms_id' is None." + assert isinstance(response['license_terms_id'], int), "'license_terms_id' is not an integer." - return response['licenseTermsId'] + return response['license_terms_id'] -def test_registerCommercialRemixPIL(story_client, registerCommercialRemixPIL): - assert registerCommercialRemixPIL is not None +def test_register_commercial_remix_pil(story_client, register_commercial_remix_pil): + assert register_commercial_remix_pil is not None @pytest.fixture(scope="module") def ip_id(story_client): @@ -119,52 +114,52 @@ def ip_id(story_client): amount=100000 * 10 ** 6) assert response is not None - assert 'ipId' in response - assert response['ipId'] is not None + assert 'ip_id' in response + assert response['ip_id'] is not None - return response['ipId'] + return response['ip_id'] -def test_attachLicenseTerms(story_client, ip_id, registerCommercialUsePIL): - license_terms_id = registerCommercialUsePIL +def test_attach_license_terms(story_client, ip_id, register_commercial_use_pil): + license_terms_id = register_commercial_use_pil - response = story_client.License.attachLicenseTerms(ip_id, PIL_LICENSE_TEMPLATE, license_terms_id) + response = story_client.License.attach_license_terms(ip_id, PIL_LICENSE_TEMPLATE, license_terms_id) assert response is not None, "Response is None, indicating the contract interaction failed." - assert 'txHash' in response, "Response does not contain 'txHash'." - assert response['txHash'] is not None, "'txHash' is None." - assert isinstance(response['txHash'], str), "'txHash' is not a string." - assert len(response['txHash']) > 0, "'txHash' is empty." + assert 'tx_hash' in response, "Response does not contain 'tx_hash'." + assert response['tx_hash'] is not None, "'tx_hash' is None." + assert isinstance(response['tx_hash'], str), "'tx_hash' is not a string." + assert len(response['tx_hash']) > 0, "'tx_hash' is empty." -def test_mintLicenseTokens(story_client, ip_id, registerCommercialUsePIL): - response = story_client.License.mintLicenseTokens( +def test_mint_license_tokens(story_client, ip_id, register_commercial_use_pil): + response = story_client.License.mint_license_tokens( licensor_ip_id=ip_id, license_template=PIL_LICENSE_TEMPLATE, - license_terms_id=registerCommercialUsePIL, + license_terms_id=register_commercial_use_pil, amount=1, receiver=account.address ) assert response is not None, "Response is None, indicating the contract interaction failed." - assert 'txHash' in response, "Response does not contain 'txHash'." - assert response['txHash'] is not None, "'txHash' is None." - assert isinstance(response['txHash'], str), "'txHash' is not a string." - assert len(response['txHash']) > 0, "'txHash' is empty." - assert 'licenseTokenIds' in response, "Response does not contain 'licenseTokenId'." - assert response['licenseTokenIds'] is not None, "'licenseTokenId' is None." - assert isinstance(response['licenseTokenIds'], list), "'licenseTokenIds' is not a list." - assert all(isinstance(i, int) for i in response['licenseTokenIds']), "Not all elements in 'licenseTokenIds' are integers." - -def test_getLicenseTerms(story_client): + assert 'tx_hash' in response, "Response does not contain 'tx_hash'." + assert response['tx_hash'] is not None, "'tx_hash' is None." + assert isinstance(response['tx_hash'], str), "'tx_hash' is not a string." + assert len(response['tx_hash']) > 0, "'tx_hash' is empty." + assert 'license_token_ids' in response, "Response does not contain 'license_token_ids'." + assert response['license_token_ids'] is not None, "'license_token_ids' is None." + assert isinstance(response['license_token_ids'], list), "'license_token_ids' is not a list." + assert all(isinstance(i, int) for i in response['license_token_ids']), "Not all elements in 'license_token_ids' are integers." + +def test_get_license_terms(story_client): selectedLicenseTermsId = 3 - response = story_client.License.getLicenseTerms(selectedLicenseTermsId) + response = story_client.License.get_license_terms(selectedLicenseTermsId) assert response is not None, "Response is None, indicating the call failed." -def test_predictMintingLicenseFee(story_client, ip_id, registerCommercialUsePIL): - response = story_client.License.predictMintingLicenseFee( +def test_predict_minting_license_fee(story_client, ip_id, register_commercial_use_pil): + response = story_client.License.predict_minting_license_fee( licensor_ip_id=ip_id, - license_terms_id=registerCommercialUsePIL, + license_terms_id=register_commercial_use_pil, amount=1 ) @@ -177,7 +172,7 @@ def test_predictMintingLicenseFee(story_client, ip_id, registerCommercialUsePIL) assert response['amount'] is not None, "'amount' is None." assert isinstance(response['amount'], int), "'amount' is not an integer." -def test_setLicensingConfig(story_client, ip_id, registerCommercialRemixPIL): +def test_set_licensing_config(story_client, ip_id, register_commercial_remix_pil): licensing_config = { 'mintingFee': 1, 'isSet': True, @@ -189,24 +184,24 @@ def test_setLicensingConfig(story_client, ip_id, registerCommercialRemixPIL): 'expectGroupRewardPool': "0x0000000000000000000000000000000000000000" } - response = story_client.License.setLicensingConfig( + response = story_client.License.set_licensing_config( ip_id=ip_id, - license_terms_id=registerCommercialRemixPIL, + license_terms_id=register_commercial_remix_pil, licensing_config=licensing_config, license_template=PIL_LICENSE_TEMPLATE ) assert response is not None, "Response is None, indicating the contract interaction failed." - assert 'txHash' in response, "Response does not contain 'txHash'" - assert response['txHash'] is not None, "'txHash' is None" - assert isinstance(response['txHash'], str), "'txHash' is not a string" - assert len(response['txHash']) > 0, "'txHash' is empty" + assert 'tx_hash' in response, "Response does not contain 'tx_hash'" + assert response['tx_hash'] is not None, "'tx_hash' is None" + assert isinstance(response['tx_hash'], str), "'tx_hash' is not a string" + assert len(response['tx_hash']) > 0, "'tx_hash' is empty" assert 'success' in response, "Response does not contain 'success'" assert response['success'] is True, "'success' is not True" def test_register_pil_terms_with_no_minting_fee(story_client): """Test registering PIL terms with no minting fee.""" - response = story_client.License.registerPILTerms( + response = story_client.License.register_pil_terms( transferable=False, royalty_policy=story_client.web3.to_checksum_address("0x0000000000000000000000000000000000000000"), default_minting_fee=0, # Minimal minting fee @@ -227,35 +222,35 @@ def test_register_pil_terms_with_no_minting_fee(story_client): ) assert response is not None - assert 'licenseTermsId' in response - assert response['licenseTermsId'] is not None - assert isinstance(response['licenseTermsId'], int) + assert 'license_terms_id' in response + assert response['license_terms_id'] is not None + assert isinstance(response['license_terms_id'], int) def test_register_commercial_use_pil_without_royalty_policy(story_client): """Test registering commercial use PIL without specifying royalty policy.""" - response = story_client.License.registerCommercialUsePIL( + response = story_client.License.register_commercial_use_pil( default_minting_fee=1, currency=MockERC20 ) assert response is not None - assert 'licenseTermsId' in response - assert response['licenseTermsId'] is not None - assert isinstance(response['licenseTermsId'], int) + assert 'license_terms_id' in response + assert response['license_terms_id'] is not None + assert isinstance(response['license_terms_id'], int) @pytest.fixture(scope="module") def setup_license_terms(story_client, ip_id): """Fixture to set up license terms for testing.""" - response = story_client.License.registerCommercialRemixPIL( + response = story_client.License.register_commercial_remix_pil( default_minting_fee=1, currency=MockERC20, commercial_rev_share=100, royalty_policy=ROYALTY_POLICY ) - license_id = response['licenseTermsId'] + license_id = response['license_terms_id'] # Attach the license terms - story_client.License.attachLicenseTerms( + story_client.License.attach_license_terms( ip_id=ip_id, license_template=PIL_LICENSE_TEMPLATE, license_terms_id=license_id @@ -265,7 +260,7 @@ def setup_license_terms(story_client, ip_id): def test_multi_token_minting(story_client, ip_id, setup_license_terms): """Test minting multiple license tokens at once.""" - response = story_client.License.mintLicenseTokens( + response = story_client.License.mint_license_tokens( licensor_ip_id=ip_id, license_template=PIL_LICENSE_TEMPLATE, license_terms_id=setup_license_terms, @@ -274,15 +269,15 @@ def test_multi_token_minting(story_client, ip_id, setup_license_terms): ) assert response is not None - assert 'txHash' in response - assert response['txHash'] is not None - assert isinstance(response['txHash'], str) - assert len(response['txHash']) > 0 - assert 'licenseTokenIds' in response - assert isinstance(response['licenseTokenIds'], list) - assert len(response['licenseTokenIds']) > 0 - -def test_set_licensing_config_with_hooks(story_client, ip_id, registerCommercialRemixPIL): + assert 'tx_hash' in response + assert response['tx_hash'] is not None + assert isinstance(response['tx_hash'], str) + assert len(response['tx_hash']) > 0 + assert 'license_token_ids' in response + assert isinstance(response['license_token_ids'], list) + assert len(response['license_token_ids']) > 0 + +def test_set_licensing_config_with_hooks(story_client, ip_id, register_commercial_remix_pil): """Test setting licensing configuration with hooks enabled.""" licensing_config = { 'mintingFee': 100, @@ -295,24 +290,24 @@ def test_set_licensing_config_with_hooks(story_client, ip_id, registerCommercial 'expectGroupRewardPool': "0x0000000000000000000000000000000000000000" } - response = story_client.License.setLicensingConfig( + response = story_client.License.set_licensing_config( ip_id=ip_id, - license_terms_id=registerCommercialRemixPIL, + license_terms_id=register_commercial_remix_pil, licensing_config=licensing_config, license_template=PIL_LICENSE_TEMPLATE ) assert response is not None - assert 'txHash' in response - assert response['txHash'] is not None - assert isinstance(response['txHash'], str) - assert len(response['txHash']) > 0 + assert 'tx_hash' in response + assert response['tx_hash'] is not None + assert isinstance(response['tx_hash'], str) + assert len(response['tx_hash']) > 0 assert 'success' in response assert response['success'] is True def test_predict_minting_fee_with_multiple_tokens(story_client, ip_id, setup_license_terms): """Test predicting minting fee for multiple tokens.""" - response = story_client.License.predictMintingLicenseFee( + response = story_client.License.predict_minting_license_fee( licensor_ip_id=ip_id, license_terms_id=setup_license_terms, amount=5 # Predict for 5 tokens diff --git a/tests/integration/test_integration_nft_client.py b/tests/integration/test_integration_nft_client.py index e890058..b069589 100644 --- a/tests/integration/test_integration_nft_client.py +++ b/tests/integration/test_integration_nft_client.py @@ -14,7 +14,7 @@ class TestNFTCollectionOperations: def test_create_basic_collection(self, story_client): """Test creating a basic NFT collection with minimum parameters""" - response = story_client.NFTClient.createNFTCollection( + response = story_client.NFTClient.create_nft_collection( name="test-collection", symbol="TEST", is_public_minting=True, @@ -24,15 +24,15 @@ def test_create_basic_collection(self, story_client): ) assert response is not None - assert 'txHash' in response - assert isinstance(response['txHash'], str) - assert len(response['txHash']) > 0 - assert 'nftContract' in response - assert Web3.is_address(response['nftContract']) + assert 'tx_hash' in response + assert isinstance(response['tx_hash'], str) + assert len(response['tx_hash']) > 0 + assert 'nft_contract' in response + assert Web3.is_address(response['nft_contract']) def test_create_collection_with_supply(self, story_client): """Test creating collection with max supply""" - response = story_client.NFTClient.createNFTCollection( + response = story_client.NFTClient.create_nft_collection( name="test-collection", symbol="TEST", max_supply=100, @@ -43,12 +43,12 @@ def test_create_collection_with_supply(self, story_client): ) assert response is not None - assert 'nftContract' in response - assert Web3.is_address(response['nftContract']) + assert 'nft_contract' in response + assert Web3.is_address(response['nft_contract']) def test_create_collection_with_mint_fee(self, story_client): """Test creating collection with mint fee configuration""" - response = story_client.NFTClient.createNFTCollection( + response = story_client.NFTClient.create_nft_collection( name="test-collection", symbol="TEST", is_public_minting=True, @@ -60,12 +60,12 @@ def test_create_collection_with_mint_fee(self, story_client): ) assert response is not None - assert 'nftContract' in response - assert Web3.is_address(response['nftContract']) + assert 'nft_contract' in response + assert Web3.is_address(response['nft_contract']) def test_create_collection_with_base_uri(self, story_client): """Test creating collection with base URI""" - response = story_client.NFTClient.createNFTCollection( + response = story_client.NFTClient.create_nft_collection( name="test-collection", symbol="TEST", is_public_minting=True, @@ -76,8 +76,8 @@ def test_create_collection_with_base_uri(self, story_client): ) assert response is not None - assert 'nftContract' in response - assert Web3.is_address(response['nftContract']) + assert 'nft_contract' in response + assert Web3.is_address(response['nft_contract']) class TestErrorCases: """Tests for error handling in NFT collection creation""" @@ -85,7 +85,7 @@ class TestErrorCases: def test_invalid_mint_fee_configuration(self, story_client): """Test error when mint fee is set but token address is invalid""" with pytest.raises(ValueError) as exc_info: - story_client.NFTClient.createNFTCollection( + story_client.NFTClient.create_nft_collection( name="test-collection", symbol="TEST", is_public_minting=True, @@ -100,7 +100,7 @@ def test_invalid_mint_fee_configuration(self, story_client): def test_invalid_recipient_address(self, story_client): """Test error when mint fee recipient address is invalid""" with pytest.raises(ValueError) as exc_info: - story_client.NFTClient.createNFTCollection( + story_client.NFTClient.create_nft_collection( name="test-collection", symbol="TEST", is_public_minting=True, @@ -115,7 +115,7 @@ class TestMintFee: @pytest.fixture(scope="module") def nft_contract(self, story_client): - response = story_client.NFTClient.createNFTCollection( + response = story_client.NFTClient.create_nft_collection( name="paid-collection", symbol="PAID", is_public_minting=True, @@ -127,14 +127,14 @@ def nft_contract(self, story_client): mint_fee_token=MockERC20, ) - return response['nftContract'] + return response['nft_contract'] def test_get_mint_fee_token(self, story_client, nft_contract): """Test successfully getting mint fee token""" - mint_fee_token = story_client.NFTClient.getMintFeeToken(nft_contract) + mint_fee_token = story_client.NFTClient.get_mint_fee_token(nft_contract) assert mint_fee_token == MockERC20 def test_get_mint_fee(self, story_client, nft_contract): """Test successfully getting mint fee""" - mint_fee = story_client.NFTClient.getMintFee(nft_contract) + mint_fee = story_client.NFTClient.get_mint_fee(nft_contract) assert mint_fee == 1000 diff --git a/tests/integration/test_integration_royalty.py b/tests/integration/test_integration_royalty.py index 8e14eca..1179f30 100644 --- a/tests/integration/test_integration_royalty.py +++ b/tests/integration/test_integration_royalty.py @@ -1,3 +1,5 @@ +# tests/integration/test_integration_royalty.py + import pytest from web3 import Web3 import copy @@ -28,30 +30,30 @@ def setup_ips_and_licenses(self, story_client): nft_contract=MockERC721, token_id=parent_token_id ) - parent_ip_id = parent_ip_response['ipId'] + parent_ip_id = parent_ip_response['ip_id'] child_token_id = get_token_id(MockERC721, story_client.web3, story_client.account) child_ip_response = story_client.IPAsset.register( nft_contract=MockERC721, token_id=child_token_id ) - child_ip_id = child_ip_response['ipId'] + child_ip_id = child_ip_response['ip_id'] - license_terms_response = story_client.License.registerCommercialRemixPIL( + license_terms_response = story_client.License.register_commercial_remix_pil( default_minting_fee=100000, currency=MockERC20, commercial_rev_share=10, royalty_policy=ROYALTY_POLICY ) - license_terms_id = license_terms_response['licenseTermsId'] + license_terms_id = license_terms_response['license_terms_id'] - story_client.License.attachLicenseTerms( + story_client.License.attach_license_terms( ip_id=parent_ip_id, license_template=PIL_LICENSE_TEMPLATE, license_terms_id=license_terms_id ) - story_client.IPAsset.registerDerivative( + story_client.IPAsset.register_derivative( child_ip_id=child_ip_id, parent_ip_ids=[parent_ip_id], license_terms_ids=[license_terms_id], @@ -87,7 +89,7 @@ def test_pay_royalty_on_behalf(self, story_client, setup_ips_and_licenses): parent_ip_id = setup_ips_and_licenses['parent_ip_id'] child_ip_id = setup_ips_and_licenses['child_ip_id'] - response = story_client.Royalty.payRoyaltyOnBehalf( + response = story_client.Royalty.pay_royalty_on_behalf( receiver_ip_id=parent_ip_id, payer_ip_id=child_ip_id, token=MockERC20, @@ -95,13 +97,13 @@ def test_pay_royalty_on_behalf(self, story_client, setup_ips_and_licenses): ) assert response is not None - assert response['txHash'] is not None and isinstance(response['txHash'], str) + assert response['tx_hash'] is not None and isinstance(response['tx_hash'], str) def test_claimable_revenue(self, story_client, setup_ips_and_licenses): """Test checking claimable revenue""" parent_ip_id = setup_ips_and_licenses['parent_ip_id'] - response = story_client.Royalty.claimableRevenue( + response = story_client.Royalty.claimable_revenue( royalty_vault_ip_id=parent_ip_id, claimer=account.address, token=MockERC20 @@ -115,7 +117,7 @@ def test_pay_royalty_unregistered_receiver(self, story_client, setup_ips_and_lic unregistered_ip_id = "0x1234567890123456789012345678901234567890" with pytest.raises(ValueError, match=f"The receiver IP with id {unregistered_ip_id} is not registered"): - story_client.Royalty.payRoyaltyOnBehalf( + story_client.Royalty.pay_royalty_on_behalf( receiver_ip_id=unregistered_ip_id, payer_ip_id=child_ip_id, token=MockERC20, @@ -128,7 +130,7 @@ def test_pay_royalty_invalid_amount(self, story_client, setup_ips_and_licenses): child_ip_id = setup_ips_and_licenses['child_ip_id'] with pytest.raises(Exception): - story_client.Royalty.payRoyaltyOnBehalf( + story_client.Royalty.pay_royalty_on_behalf( receiver_ip_id=parent_ip_id, payer_ip_id=child_ip_id, token=MockERC20, @@ -139,7 +141,7 @@ class TestClaimAllRevenue: @pytest.fixture(scope="module") def setup_claim_all_revenue(self, story_client): # Create NFT collection - collection_response = story_client.NFTClient.createNFTCollection( + collection_response = story_client.NFTClient.create_nft_collection( name="free-collection", symbol="FREE", max_supply=100, @@ -148,7 +150,7 @@ def setup_claim_all_revenue(self, story_client): contract_uri="test-uri", mint_fee_recipient=ZERO_ADDRESS ) - spg_nft_contract = collection_response['nftContract'] + spg_nft_contract = collection_response['nft_contract'] # Define license terms data template license_terms_template = [{ @@ -213,45 +215,45 @@ def setup_claim_all_revenue(self, story_client): } # Register IP A with PIL terms - ip_a_response = story_client.IPAsset.mintAndRegisterIpAssetWithPilTerms( + ip_a_response = story_client.IPAsset.mint_and_register_ip_asset_with_pil_terms( spg_nft_contract=spg_nft_contract, terms=copy.deepcopy(license_terms_template), ip_metadata=metadata_a ) - ip_a = ip_a_response['ipId'] - license_terms_id = ip_a_response['licenseTermsIds'][0] + ip_a = ip_a_response['ip_id'] + license_terms_id = ip_a_response['license_terms_ids'][0] # Register IP B as derivative of A - ip_b_response = story_client.IPAsset.mintAndRegisterIp( + ip_b_response = story_client.IPAsset.mint_and_register_ip( spg_nft_contract=spg_nft_contract, ip_metadata=metadata_b ) - ip_b = ip_b_response['ipId'] - story_client.IPAsset.registerDerivative( + ip_b = ip_b_response['ip_id'] + story_client.IPAsset.register_derivative( child_ip_id=ip_b, parent_ip_ids=[ip_a], license_terms_ids=[license_terms_id] ) # Register IP C as derivative of B - ip_c_response = story_client.IPAsset.mintAndRegisterIp( + ip_c_response = story_client.IPAsset.mint_and_register_ip( spg_nft_contract=spg_nft_contract, ip_metadata=metadata_c ) - ip_c = ip_c_response['ipId'] - story_client.IPAsset.registerDerivative( + ip_c = ip_c_response['ip_id'] + story_client.IPAsset.register_derivative( child_ip_id=ip_c, parent_ip_ids=[ip_b], license_terms_ids=[license_terms_id] ) # Register IP D as derivative of C - ip_d_response = story_client.IPAsset.mintAndRegisterIp( + ip_d_response = story_client.IPAsset.mint_and_register_ip( spg_nft_contract=spg_nft_contract, ip_metadata=metadata_d ) - ip_d = ip_d_response['ipId'] - story_client.IPAsset.registerDerivative( + ip_d = ip_d_response['ip_id'] + story_client.IPAsset.register_derivative( child_ip_id=ip_d, parent_ip_ids=[ip_c], license_terms_ids=[license_terms_id] @@ -265,7 +267,7 @@ def setup_claim_all_revenue(self, story_client): } def test_claim_all_revenue(self, setup_claim_all_revenue, story_client): - response = story_client.Royalty.claimAllRevenue( + response = story_client.Royalty.claim_all_revenue( ancestor_ip_id=setup_claim_all_revenue['ip_a'], claimer=setup_claim_all_revenue['ip_a'], child_ip_ids=[setup_claim_all_revenue['ip_b'], setup_claim_all_revenue['ip_c']], @@ -274,15 +276,15 @@ def test_claim_all_revenue(self, setup_claim_all_revenue, story_client): ) assert response is not None - assert 'txHashes' in response - assert isinstance(response['txHashes'], list) - assert len(response['txHashes']) > 0 - assert response['claimedTokens'][0]['amount'] == 120 + assert 'tx_hashes' in response + assert isinstance(response['tx_hashes'], list) + assert len(response['tx_hashes']) > 0 + assert response['claimed_tokens'][0]['amount'] == 120 @pytest.fixture(scope="module") def setup_claim_all_revenue_claim_options(self, story_client): # Create NFT collection - collection_response = story_client.NFTClient.createNFTCollection( + collection_response = story_client.NFTClient.create_nft_collection( name="free-collection", symbol="FREE", max_supply=100, @@ -291,7 +293,7 @@ def setup_claim_all_revenue_claim_options(self, story_client): contract_uri="test-uri", mint_fee_recipient=ZERO_ADDRESS ) - spg_nft_contract = collection_response['nftContract'] + spg_nft_contract = collection_response['nft_contract'] # Define license terms data template license_terms_template = [{ @@ -356,45 +358,45 @@ def setup_claim_all_revenue_claim_options(self, story_client): } # Register IP A with PIL terms - ip_a_response = story_client.IPAsset.mintAndRegisterIpAssetWithPilTerms( + ip_a_response = story_client.IPAsset.mint_and_register_ip_asset_with_pil_terms( spg_nft_contract=spg_nft_contract, terms=copy.deepcopy(license_terms_template), ip_metadata=metadata_a ) - ip_a = ip_a_response['ipId'] - license_terms_id = ip_a_response['licenseTermsIds'][0] + ip_a = ip_a_response['ip_id'] + license_terms_id = ip_a_response['license_terms_ids'][0] # Register IP B as derivative of A - ip_b_response = story_client.IPAsset.mintAndRegisterIp( + ip_b_response = story_client.IPAsset.mint_and_register_ip( spg_nft_contract=spg_nft_contract, ip_metadata=metadata_b ) - ip_b = ip_b_response['ipId'] - ip_b_derivative_response = story_client.IPAsset.registerDerivative( + ip_b = ip_b_response['ip_id'] + ip_b_derivative_response = story_client.IPAsset.register_derivative( child_ip_id=ip_b, parent_ip_ids=[ip_a], license_terms_ids=[license_terms_id] ) # Register IP C as derivative of B - ip_c_response = story_client.IPAsset.mintAndRegisterIp( + ip_c_response = story_client.IPAsset.mint_and_register_ip( spg_nft_contract=spg_nft_contract, ip_metadata=metadata_c ) - ip_c = ip_c_response['ipId'] - story_client.IPAsset.registerDerivative( + ip_c = ip_c_response['ip_id'] + story_client.IPAsset.register_derivative( child_ip_id=ip_c, parent_ip_ids=[ip_b], license_terms_ids=[license_terms_id] ) # Register IP D as derivative of C - ip_d_response = story_client.IPAsset.mintAndRegisterIp( + ip_d_response = story_client.IPAsset.mint_and_register_ip( spg_nft_contract=spg_nft_contract, ip_metadata=metadata_d ) - ip_d = ip_d_response['ipId'] - story_client.IPAsset.registerDerivative( + ip_d = ip_d_response['ip_id'] + story_client.IPAsset.register_derivative( child_ip_id=ip_d, parent_ip_ids=[ip_c], license_terms_ids=[license_terms_id] @@ -409,19 +411,19 @@ def setup_claim_all_revenue_claim_options(self, story_client): def test_claim_all_revenue_claim_options(self, setup_claim_all_revenue_claim_options, story_client): """Test claiming all revenue with specific claim options""" - response = story_client.Royalty.claimAllRevenue( + response = story_client.Royalty.claim_all_revenue( ancestor_ip_id=setup_claim_all_revenue_claim_options['ip_a'], claimer=setup_claim_all_revenue_claim_options['ip_a'], child_ip_ids=[setup_claim_all_revenue_claim_options['ip_b'], setup_claim_all_revenue_claim_options['ip_c']], royalty_policies=[ROYALTY_POLICY, ROYALTY_POLICY], currency_tokens=[MockERC20, MockERC20], claim_options={ - 'autoTransferAllClaimedTokensFromIp': True + 'auto_transfer_all_claimed_tokens_from_ip': True } ) assert response is not None - assert 'txHashes' in response - assert isinstance(response['txHashes'], list) - assert len(response['txHashes']) > 0 - assert response['claimedTokens'][0]['amount'] == 120 \ No newline at end of file + assert 'tx_hashes' in response + assert isinstance(response['tx_hashes'], list) + assert len(response['tx_hashes']) > 0 + assert response['claimed_tokens'][0]['amount'] == 120 \ No newline at end of file diff --git a/tests/integration/test_integration_wip.py b/tests/integration/test_integration_wip.py index 9261030..bf7aa95 100644 --- a/tests/integration/test_integration_wip.py +++ b/tests/integration/test_integration_wip.py @@ -1,10 +1,11 @@ +# tests/integration/test_integration_wip.py + import pytest from web3 import Web3 from setup_for_integration import ( web3, story_client, - story_client_2, wallet_address, wallet_address_2 ) @@ -15,8 +16,8 @@ def test_deposit(self, story_client): ip_amt = Web3.to_wei(1, 'ether') # or Web3.to_wei("0.01", 'ether') # Get balances before deposit - balance_before = story_client.getWalletBalance() - wip_before = story_client.WIP.balanceOf(wallet_address) + balance_before = story_client.get_wallet_balance() + wip_before = story_client.WIP.balance_of(wallet_address) # Deposit IP to WIP response = story_client.WIP.deposit( @@ -24,17 +25,17 @@ def test_deposit(self, story_client): ) # Verify transaction hash - assert isinstance(response['txHash'], str) + assert isinstance(response['tx_hash'], str) # Get balances after deposit - balance_after = story_client.getWalletBalance() - wip_after = story_client.WIP.balanceOf(wallet_address) + balance_after = story_client.get_wallet_balance() + wip_after = story_client.WIP.balance_of(wallet_address) # 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["txHash"], timeout=300) + tx_receipt = web3.eth.wait_for_transaction_receipt(response["tx_hash"], timeout=300) gas_cost = tx_receipt['gasUsed'] * tx_receipt['effectiveGasPrice'] # Verify wallet balance decreased by deposit amount plus gas cost @@ -47,8 +48,8 @@ def test_transfer(self, story_client): transfer_amount = Web3.to_wei("0.01", 'ether') # Get balances before transfer - sender_wip_before = story_client.WIP.balanceOf(wallet_address) - receiver_wip_before = story_client.WIP.balanceOf(wallet_address_2) + sender_wip_before = story_client.WIP.balance_of(wallet_address) + receiver_wip_before = story_client.WIP.balance_of(wallet_address_2) # Transfer WIP to wallet_address_2 response = story_client.WIP.transfer( @@ -58,11 +59,11 @@ def test_transfer(self, story_client): ) # Verify transaction hash - assert isinstance(response['txHash'], str) + assert isinstance(response['tx_hash'], str) # Get balances after transfer - sender_wip_after = story_client.WIP.balanceOf(wallet_address) - receiver_wip_after = story_client.WIP.balanceOf(wallet_address_2) + sender_wip_after = story_client.WIP.balance_of(wallet_address) + receiver_wip_after = story_client.WIP.balance_of(wallet_address_2) # Verify sender's WIP balance decreased by transfer amount assert sender_wip_after == sender_wip_before - transfer_amount @@ -77,8 +78,8 @@ class TestWIPWithdraw: def test_withdraw(self, story_client): """Test withdrawing WIP to IP""" # Get balances before withdrawal - balance_before = story_client.getWalletBalance() - wip_before = story_client.WIP.balanceOf(wallet_address) + balance_before = story_client.get_wallet_balance() + wip_before = story_client.WIP.balance_of(wallet_address) # Withdraw all WIP response = story_client.WIP.withdraw( @@ -87,17 +88,17 @@ def test_withdraw(self, story_client): ) # Verify transaction hash - assert isinstance(response['txHash'], str) + assert isinstance(response['tx_hash'], str) # Get balances after withdrawal - wip_after = story_client.WIP.balanceOf(wallet_address) - balance_after = story_client.getWalletBalance() + wip_after = story_client.WIP.balance_of(wallet_address) + balance_after = story_client.get_wallet_balance() # Verify WIP balance is now zero assert wip_after == 0 # Calculate gas cost - tx_receipt = web3.eth.wait_for_transaction_receipt(response["txHash"], timeout=300) + tx_receipt = web3.eth.wait_for_transaction_receipt(response["tx_hash"], timeout=300) gas_cost = tx_receipt['gasUsed'] * tx_receipt['effectiveGasPrice'] # Verify wallet balance increased by withdrawal amount minus gas cost diff --git a/tests/integration/utils.py b/tests/integration/utils.py index 81b0bdf..ea205a1 100644 --- a/tests/integration/utils.py +++ b/tests/integration/utils.py @@ -172,7 +172,7 @@ def approve(erc20_contract_address, web3, account, spender_address, amount): return tx_receipt -def getBlockTimestamp(web3): +def get_block_timestamp(web3): return (web3.eth.get_block('latest'))['timestamp'] def check_event_in_tx(web3, tx_hash: str, event_text: str) -> bool: diff --git a/tests/unit/resources/test_ip_account.py b/tests/unit/resources/test_ip_account.py index ea655ec..1f844cb 100644 --- a/tests/unit/resources/test_ip_account.py +++ b/tests/unit/resources/test_ip_account.py @@ -16,6 +16,7 @@ # Constants ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" +ZERO_HASH = "0x0000000000000000000000000000000000000000000000000000000000000000" VALID_IP_ID = "0x1daAE3197Bc469Cb97B917aa460a12dD95c6627c" TX_HASH = "0xe87b172eee35872179ced53ea4f3f314b12cd0f5d0034e7f0ae3c4efce9ba6f1" @@ -27,7 +28,7 @@ def __init__(self): @staticmethod def to_checksum_address(address): if not is_address(address): - raise ValueError(f"The recipient of the transaction {address} is not a valid address") + raise ValueError(f"Invalid address: {address}") return to_checksum_address(address) @staticmethod @@ -60,8 +61,6 @@ def ip_account(mock_web3, mock_account): chain_id = 11155111 # Sepolia chain ID return IPAccount(mock_web3, mock_account, chain_id) -@pytest.mark.unit -@pytest.mark.unit @pytest.mark.unit class TestExecute: def test_invalid_recipient_address(self, ip_account): @@ -84,10 +83,10 @@ def test_successful_transaction(self, ip_account): mock_signed_txn = MagicMock() mock_signed_txn.raw_transaction = b'raw_transaction_bytes' - # Mock transaction hash with hex method that returns hash WITHOUT '0x' prefix + # Mock transaction hash with hex method that returns hash class MockTxHash: def hex(self): - return TX_HASH[2:] # Remove '0x' prefix when returning the hash + return TX_HASH mock_tx_hash = MockTxHash() @@ -100,7 +99,7 @@ def hex(self): patch.object(ip_account.web3.eth, 'wait_for_transaction_receipt', return_value={'status': 1}): response = ip_account.execute(to_address, value, VALID_IP_ID, data) - assert response['txHash'] == TX_HASH[2:] + assert response['tx_hash'] == TX_HASH def test_wait_for_transaction(self, ip_account): to_address = "0xF9936a224b3Deb6f9A4645ccAfa66f7ECe83CF0A" @@ -113,7 +112,7 @@ def test_wait_for_transaction(self, ip_account): class MockTxHash: def hex(self): - return TX_HASH[2:] # Remove '0x' prefix when returning the hash + return TX_HASH mock_tx_hash = MockTxHash() @@ -125,7 +124,7 @@ def hex(self): patch.object(ip_account.web3.eth, 'wait_for_transaction_receipt', return_value={'status': 1}): response = ip_account.execute(to_address, value, VALID_IP_ID, data, tx_options=tx_options) - assert response['txHash'] == TX_HASH[2:] + assert response['tx_hash'] == TX_HASH def test_encoded_tx_data_only(self, ip_account): to_address = "0xF9936a224b3Deb6f9A4645ccAfa66f7ECe83CF0A" @@ -157,7 +156,7 @@ def test_encoded_tx_data_only(self, ip_account): class TestExecuteWithSig: def test_invalid_recipient_address(self, ip_account): with pytest.raises(ValueError) as exc_info: - ip_account.executeWithSig( + ip_account.execute_with_sig( VALID_IP_ID, "0xInvalidAddress", "0x11111111111111111111111111111", @@ -180,7 +179,7 @@ def test_successful_transaction_with_sig(self, ip_account): class MockTxHash: def hex(self): - return TX_HASH[2:] + return TX_HASH mock_tx_hash = MockTxHash() @@ -191,8 +190,8 @@ def hex(self): patch.object(ip_account.web3.eth, 'send_raw_transaction', return_value=mock_tx_hash), \ patch.object(ip_account.web3.eth, 'wait_for_transaction_receipt', return_value={'status': 1}): - response = ip_account.executeWithSig(VALID_IP_ID, to_address, data, signer, deadline, signature, value) - assert response['txHash'] == TX_HASH[2:] + response = ip_account.execute_with_sig(VALID_IP_ID, to_address, data, signer, deadline, signature, value) + assert response['tx_hash'] == TX_HASH def test_wait_for_transaction_with_sig(self, ip_account): to_address = "0xF9936a224b3Deb6f9A4645ccAfa66f7ECe83CF0A" @@ -207,7 +206,7 @@ def test_wait_for_transaction_with_sig(self, ip_account): class MockTxHash: def hex(self): - return TX_HASH[2:] # Remove '0x' prefix when returning the hash + return TX_HASH mock_tx_hash = MockTxHash() @@ -218,16 +217,16 @@ def hex(self): patch.object(ip_account.web3.eth, 'send_raw_transaction', return_value=mock_tx_hash), \ patch.object(ip_account.web3.eth, 'wait_for_transaction_receipt', return_value={'status': 1}): - response = ip_account.executeWithSig( + response = ip_account.execute_with_sig( VALID_IP_ID, to_address, data, signer, deadline, signature, tx_options=tx_options ) - assert response['txHash'] == TX_HASH[2:] + assert response['tx_hash'] == TX_HASH class TestGetIpAccountNonce: def test_invalid_ip_id(self, ip_account): with pytest.raises(ValueError) as exc_info: - ip_account.getIpAccountNonce("0x123") # invalid address + ip_account.get_ip_account_nonce("0x123") # invalid address assert "Invalid IP id address" in str(exc_info.value) def test_successful_nonce_retrieval(self, ip_account): @@ -237,25 +236,141 @@ def test_successful_nonce_retrieval(self, ip_account): with patch('story_protocol_python_sdk.abi.IPAccountImpl.IPAccountImpl_client.IPAccountImplClient.state', return_value=expected_nonce), \ patch('web3.eth.Eth.contract', return_value=MagicMock()): - nonce = ip_account.getIpAccountNonce(ip_id) + nonce = ip_account.get_ip_account_nonce(ip_id) assert nonce == expected_nonce class TestGetToken: def test_invalid_ip_id(self, ip_account): with pytest.raises(ValueError) as exc_info: - ip_account.getToken("0x123") # invalid address + ip_account.get_token("0x123") # invalid address assert "Invalid IP id address" in str(exc_info.value) def test_successful_token_retrieval(self, ip_account): ip_id = Web3.to_checksum_address("0x73fcb515cee99e4991465ef586cfe2b072ebb512") expected_token = { - 'chainId': 1513, - 'tokenContract': ZERO_ADDRESS, - 'tokenId': 1 + 'chain_id': 1513, + 'token_contract': ZERO_ADDRESS, + 'token_id': 1 } with patch('story_protocol_python_sdk.abi.IPAccountImpl.IPAccountImpl_client.IPAccountImplClient.token', return_value=[1513, ZERO_ADDRESS, 1]), \ patch('web3.eth.Eth.contract', return_value=MagicMock()): - token = ip_account.getToken(ip_id) - assert token == expected_token \ No newline at end of file + token = ip_account.get_token(ip_id) + assert token == expected_token + +class TestTransferERC20: + def test_unregistered_ip_id(self, ip_account): + with patch.object(ip_account, '_is_registered', return_value=False): + with pytest.raises(ValueError) as exc_info: + ip_account.transfer_erc20( + ip_id=VALID_IP_ID, + tokens=[{ + 'address': ZERO_ADDRESS, + 'target': ZERO_ADDRESS, + 'amount': 1000 + }] + ) + assert f"IP id {VALID_IP_ID} is not registered" in str(exc_info.value) + + def test_invalid_token_params(self, ip_account): + with patch.object(ip_account, '_is_registered', return_value=True): + with pytest.raises(ValueError) as exc_info: + ip_account.transfer_erc20( + ip_id=VALID_IP_ID, + tokens=[{ + # Missing 'address' + 'target': ZERO_ADDRESS, + 'amount': 1000 + }] + ) + assert "Each token transfer must include 'address', 'target', and 'amount'" in str(exc_info.value) + + def test_successful_transfer(self, ip_account): + tokens = [ + { + 'address': "0x1daAE3197Bc469Cb97B917aa460a12dD95c6627c", + 'target': "0xF60cBF0Ea1A61567F1dDaf79A6219D20d189155c", + 'amount': 1000000 + }, + { + 'address': "0x2daAE3197Bc469Cb97B917aa460a12dD95c6627c", + 'target': "0xF60cBF0Ea1A61567F1dDaf79A6219D20d189155c", + 'amount': 2000000 + } + ] + + mock_signed_txn = MagicMock() + mock_signed_txn.raw_transaction = b'raw_transaction_bytes' + + class MockTxHash: + def hex(self): + return TX_HASH + + mock_tx_hash = MockTxHash() + + ip_account.account.sign_transaction = MagicMock(return_value=mock_signed_txn) + + with patch.object(ip_account, '_is_registered', return_value=True), \ + patch.object(ip_account.web3.eth, 'get_transaction_count', return_value=0), \ + patch.object(ip_account.web3.eth, 'send_raw_transaction', return_value=mock_tx_hash), \ + patch.object(ip_account.web3.eth, 'wait_for_transaction_receipt', return_value={'status': 1}): + + response = ip_account.transfer_erc20(VALID_IP_ID, tokens) + assert response['tx_hash'] == TX_HASH + +class TestSetIPMetadata: + def test_unregistered_ip_id(self, ip_account): + with patch.object(ip_account, '_is_registered', return_value=False): + with pytest.raises(ValueError) as exc_info: + ip_account.set_ip_metadata( + ip_id=VALID_IP_ID, + metadata_uri="ipfs://example", + metadata_hash=ZERO_HASH + ) + assert f"IP id {VALID_IP_ID} is not registered" in str(exc_info.value) + + def test_successful_metadata_update(self, ip_account): + metadata_uri = "ipfs://example" + metadata_hash = ZERO_HASH + + mock_signed_txn = MagicMock() + mock_signed_txn.raw_transaction = b'raw_transaction_bytes' + + class MockTxHash: + def hex(self): + return TX_HASH + + mock_tx_hash = MockTxHash() + + # Create a mock contract with a valid address + mock_contract = MagicMock() + mock_contract.address = "0xF9936a224b3Deb6f9A4645ccAfa66f7ECe83CF0A" # Use a valid address + + ip_account.account.sign_transaction = MagicMock(return_value=mock_signed_txn) + + with patch.object(ip_account, '_is_registered', return_value=True), \ + patch.object(ip_account.web3.eth, 'get_transaction_count', return_value=0), \ + patch.object(ip_account.web3.eth, 'send_raw_transaction', return_value=mock_tx_hash), \ + patch.object(ip_account.web3.eth, 'wait_for_transaction_receipt', return_value={'status': 1}), \ + patch.object(ip_account.web3.eth, 'contract', return_value=mock_contract), \ + patch.object(ip_account.web3, 'is_address', return_value=True): + + response = ip_account.set_ip_metadata(VALID_IP_ID, metadata_uri, metadata_hash) + assert response['tx_hash'] == TX_HASH + +class TestOwner: + def test_invalid_ip_id(self, ip_account): + with pytest.raises(ValueError) as exc_info: + ip_account.owner("0x123") # invalid address + assert "Invalid IP id address" in str(exc_info.value) + + def test_successful_owner_retrieval(self, ip_account): + ip_id = Web3.to_checksum_address("0x73fcb515cee99e4991465ef586cfe2b072ebb512") + expected_owner = "0xF60cBF0Ea1A61567F1dDaf79A6219D20d189155c" + + with patch('story_protocol_python_sdk.abi.IPAccountImpl.IPAccountImpl_client.IPAccountImplClient.owner', + return_value=expected_owner), \ + patch('web3.eth.Eth.contract', return_value=MagicMock()): + owner = ip_account.owner(ip_id) + assert owner == expected_owner diff --git a/tests/unit/resources/test_ip_asset.py b/tests/unit/resources/test_ip_asset.py index e641984..b57525b 100644 --- a/tests/unit/resources/test_ip_asset.py +++ b/tests/unit/resources/test_ip_asset.py @@ -36,6 +36,10 @@ def to_wei(number, unit): @staticmethod def is_address(address): return is_address(address) + + @staticmethod + def keccak(text=None): + return Web3.keccak(text=text) def is_connected(self): return True @@ -59,14 +63,14 @@ class TestIPAssetRegister: def test_register_invalid_deadline_type(self, ip_asset): with patch.object(ip_asset, '_get_ip_id', return_value="0xd142822Dc1674154EaF4DDF38bbF7EF8f0D8ECe4"), \ patch.object(ip_asset, '_is_registered', return_value=False): - with pytest.raises(ValueError, match="Invalid deadline value."): + with pytest.raises(ValueError): ip_asset.register( nft_contract="0x1daAE3197Bc469Cb97B917aa460a12dD95c6627c", token_id=3, deadline="error", ip_metadata={ - 'ipMetadataURI': "1", - 'ipMetadataHash': ZERO_HASH + 'ip_metadata_uri': "1", + 'ip_metadata_hash': ZERO_HASH } ) @@ -75,11 +79,11 @@ def test_register_already_registered(self, ip_asset): token_id = 3 ip_id = "0xd142822Dc1674154EaF4DDF38bbF7EF8f0D8ECe4" - with patch.object(ip_asset.ip_asset_registry_client, 'ipId', return_value=ip_id), \ - patch.object(ip_asset.ip_asset_registry_client, 'isRegistered', return_value=True): + with patch.object(ip_asset, '_get_ip_id', return_value=ip_id), \ + patch.object(ip_asset, '_is_registered', return_value=True): response = ip_asset.register(token_contract, token_id) - assert response['ipId'] == ip_id - assert response['txHash'] is None + assert response['ip_id'] == ip_id + assert response['tx_hash'] is None def test_register_successful(self, ip_asset): token_contract = "0x1daAE3197Bc469Cb97B917aa460a12dD95c6627c" @@ -90,7 +94,7 @@ def test_register_successful(self, ip_asset): class MockTxHash: def hex(self): - return tx_hash[2:] + return tx_hash mock_tx_hash = MockTxHash() @@ -105,11 +109,11 @@ def hex(self): patch.object(ip_asset.web3.eth, 'get_transaction_count', return_value=0), \ patch.object(ip_asset.web3.eth, 'send_raw_transaction', return_value=mock_tx_hash), \ patch.object(ip_asset.web3.eth, 'wait_for_transaction_receipt', return_value={'status': 1, 'logs': []}), \ - patch.object(ip_asset, '_parse_tx_ip_registered_event', return_value={'ipId': ip_id}): + patch.object(ip_asset, '_parse_tx_ip_registered_event', return_value={'ip_id': ip_id}): result = ip_asset.register(token_contract, token_id) - assert result['txHash'] == tx_hash[2:] - assert result['ipId'] == ip_id + assert result['tx_hash'] == tx_hash + assert result['ip_id'] == ip_id def test_register_with_metadata(self, ip_asset): token_contract = "0x1daAE3197Bc469Cb97B917aa460a12dD95c6627c" @@ -118,17 +122,17 @@ def test_register_with_metadata(self, ip_asset): tx_hash = "0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997" metadata = { - 'ipMetadataURI': "", - 'ipMetadataHash': ZERO_HASH, - 'nftMetadataURI': "", - 'nftMetadataHash': ZERO_HASH, + 'ip_metadata_uri': "", + 'ip_metadata_hash': ZERO_HASH, + 'nft_metadata_uri': "", + 'nft_metadata_hash': ZERO_HASH, } calculated_deadline = 1000 class MockTxHash: def hex(self): - return tx_hash[2:] + return tx_hash mock_tx_hash = MockTxHash() @@ -144,7 +148,7 @@ def hex(self): patch.object(ip_asset.web3.eth, 'get_transaction_count', return_value=0), \ patch.object(ip_asset.web3.eth, 'send_raw_transaction', return_value=mock_tx_hash), \ patch.object(ip_asset.web3.eth, 'wait_for_transaction_receipt', return_value={'status': 1, 'logs': []}), \ - patch.object(ip_asset, '_parse_tx_ip_registered_event', return_value={'ipId': ip_id}): + patch.object(ip_asset, '_parse_tx_ip_registered_event', return_value={'ip_id': ip_id, 'token_id': token_id}): result = ip_asset.register( nft_contract=token_contract, @@ -153,5 +157,5 @@ def hex(self): deadline=1000 ) - assert result['txHash'] == tx_hash[2:] - assert result['ipId'] == ip_id \ No newline at end of file + assert result['tx_hash'] == tx_hash + assert result['ip_id'] == ip_id \ No newline at end of file diff --git a/tests/unit/resources/test_license.py b/tests/unit/resources/test_license.py index e66ad1b..425b693 100644 --- a/tests/unit/resources/test_license.py +++ b/tests/unit/resources/test_license.py @@ -76,7 +76,7 @@ def license_client(mock_web3, mock_account): class TestPILTermsRegistration: """Tests for PIL (Programmable IP License) terms registration.""" - def test_registerPILTerms_license_terms_id_registered(self, license_client): + def test_register_pil_terms_license_terms_id_registered(self, license_client): with patch.object(license_client.license_template_client, 'getLicenseTermsId', return_value=1), \ patch.object(license_client.license_terms_util.royalty_module_client, 'isWhitelistedRoyaltyPolicy', return_value=True), \ patch.object(license_client.license_terms_util.royalty_module_client, 'isWhitelistedRoyaltyToken', return_value=True): @@ -101,11 +101,11 @@ def test_registerPILTerms_license_terms_id_registered(self, license_client): 'uri': '' } - response = license_client.registerPILTerms(**license_terms) - assert response['licenseTermsId'] == 1 - assert 'txHash' not in response + response = license_client.register_pil_terms(**license_terms) + assert response['license_terms_id'] == 1 + assert 'tx_hash' not in response - def test_registerPILTerms_success(self, license_client, mock_signed_txn, mock_account): + def test_register_pil_terms_success(self, license_client, mock_signed_txn, mock_account): with patch.object(license_client.license_template_client, 'getLicenseTermsId', return_value=0), \ patch.object(license_client.license_terms_util.royalty_module_client, 'isWhitelistedRoyaltyPolicy', return_value=True), \ patch.object(license_client.license_terms_util.royalty_module_client, 'isWhitelistedRoyaltyToken', return_value=True), \ @@ -115,7 +115,7 @@ def test_registerPILTerms_success(self, license_client, mock_signed_txn, mock_ac patch.object(license_client.web3.eth, 'send_raw_transaction', return_value=MockTxHash()), \ patch.object(license_client.web3.eth, 'wait_for_transaction_receipt', return_value=MagicMock()): - response = license_client.registerPILTerms( + response = license_client.register_pil_terms( transferable=False, royalty_policy=VALID_ADDRESS, default_minting_fee=1513, @@ -135,17 +135,17 @@ def test_registerPILTerms_success(self, license_client, mock_signed_txn, mock_ac uri='' ) - assert 'txHash' in response - assert response['txHash'] == TX_HASH[2:] - assert isinstance(response['txHash'], str) + assert 'tx_hash' in response + assert response['tx_hash'] == TX_HASH[2:] + assert isinstance(response['tx_hash'], str) - def test_registerPILTerms_commercial_rev_share_error_more_than_100(self, license_client): + def test_register_pil_terms_commercial_rev_share_error_more_than_100(self, license_client): with patch.object(license_client.license_template_client, 'getLicenseTermsId', return_value=0), \ patch.object(license_client.license_terms_util.royalty_module_client, 'isWhitelistedRoyaltyPolicy', return_value=True), \ patch.object(license_client.license_terms_util.royalty_module_client, 'isWhitelistedRoyaltyToken', return_value=True): with pytest.raises(ValueError, match='CommercialRevShare should be between 0 and 100.'): - license_client.registerPILTerms( + license_client.register_pil_terms( transferable=False, royalty_policy=VALID_ADDRESS, default_minting_fee=1, @@ -165,13 +165,13 @@ def test_registerPILTerms_commercial_rev_share_error_more_than_100(self, license uri='' ) - def test_registerPILTerms_commercial_rev_share_error_less_than_0(self, license_client): + def test_register_pil_terms_commercial_rev_share_error_less_than_0(self, license_client): with patch.object(license_client.license_template_client, 'getLicenseTermsId', return_value=0), \ patch.object(license_client.license_terms_util.royalty_module_client, 'isWhitelistedRoyaltyPolicy', return_value=True), \ patch.object(license_client.license_terms_util.royalty_module_client, 'isWhitelistedRoyaltyToken', return_value=True): with pytest.raises(ValueError, match='CommercialRevShare should be between 0 and 100.'): - license_client.registerPILTerms( + license_client.register_pil_terms( transferable=False, royalty_policy=VALID_ADDRESS, default_minting_fee=1, @@ -193,13 +193,13 @@ def test_registerPILTerms_commercial_rev_share_error_less_than_0(self, license_c class TestNonComSocialRemixingPIL: """Tests for non-commercial social remixing PIL functionality.""" - def test_registerNonComSocialRemixingPIL_license_terms_id_registered(self, license_client): + def test_register_non_com_social_remixing_pil_license_terms_id_registered(self, license_client): with patch.object(license_client.license_template_client, 'getLicenseTermsId', return_value=1): - response = license_client.registerNonComSocialRemixingPIL() - assert response['licenseTermsId'] == 1 - assert 'txHash' not in response + response = license_client.register_non_com_social_remixing_pil() + assert response['license_terms_id'] == 1 + assert 'tx_hash' not in response - def test_registerNonComSocialRemixingPIL_success(self, license_client, mock_signed_txn, mock_account): + def test_register_non_com_social_remixing_pil_success(self, license_client, mock_signed_txn, mock_account): with patch.object(license_client.license_template_client, 'getLicenseTermsId', return_value=0), \ patch.object(license_client.license_template_client, 'build_registerLicenseTerms_transaction', return_value={'from': mock_account.address, 'nonce': 1, 'gas': 2000000, 'gasPrice': Web3.to_wei('100', 'gwei')}), \ @@ -209,35 +209,35 @@ def test_registerNonComSocialRemixingPIL_success(self, license_client, mock_sign patch.object(license_client.web3.eth, 'wait_for_transaction_receipt', return_value=MagicMock()), \ patch.object(license_client, '_parse_tx_license_terms_registered_event', return_value=1): - response = license_client.registerNonComSocialRemixingPIL() - assert 'txHash' in response - assert response['txHash'] == TX_HASH[2:] - assert isinstance(response['txHash'], str) - assert 'licenseTermsId' in response - assert response['licenseTermsId'] == 1 + response = license_client.register_non_com_social_remixing_pil() + assert 'tx_hash' in response + assert response['tx_hash'] == TX_HASH[2:] + assert isinstance(response['tx_hash'], str) + assert 'license_terms_id' in response + assert response['license_terms_id'] == 1 - def test_registerNonComSocialRemixingPIL_error(self, license_client): + def test_register_non_com_social_remixing_pil_error(self, license_client): with patch.object(license_client.license_template_client, 'getLicenseTermsId', return_value=0), \ patch.object(license_client.license_terms_util.royalty_module_client, 'isWhitelistedRoyaltyPolicy', return_value=True), \ patch.object(license_client.license_template_client, 'build_registerLicenseTerms_transaction', side_effect=Exception("request fail.")): with pytest.raises(Exception, match="request fail."): - license_client.registerNonComSocialRemixingPIL() + license_client.register_non_com_social_remixing_pil() class TestCommercialUsePIL: """Tests for commercial use PIL functionality.""" - def test_registerCommercialUsePIL_license_terms_id_registered(self, license_client): + def test_register_commercial_use_pil_license_terms_id_registered(self, license_client): with patch.object(license_client.license_template_client, 'getLicenseTermsId', return_value=1): - response = license_client.registerCommercialUsePIL( + response = license_client.register_commercial_use_pil( default_minting_fee=1, currency=ZERO_ADDRESS ) - assert response['licenseTermsId'] == 1 - assert 'txHash' not in response + assert response['license_terms_id'] == 1 + assert 'tx_hash' not in response - def test_registerCommercialUsePIL_success(self, license_client, mock_signed_txn, mock_account): + def test_register_commercial_use_pil_success(self, license_client, mock_signed_txn, mock_account): with patch.object(license_client.license_template_client, 'getLicenseTermsId', return_value=0), \ patch.object(license_client.license_terms_util.royalty_module_client, 'isWhitelistedRoyaltyPolicy', return_value=True), \ patch.object(license_client.license_template_client, 'build_registerLicenseTerms_transaction', @@ -248,23 +248,23 @@ def test_registerCommercialUsePIL_success(self, license_client, mock_signed_txn, patch.object(license_client.web3.eth, 'wait_for_transaction_receipt', return_value=MagicMock()), \ patch.object(license_client, '_parse_tx_license_terms_registered_event', return_value=1): - response = license_client.registerCommercialUsePIL( + response = license_client.register_commercial_use_pil( default_minting_fee=1, currency=ZERO_ADDRESS ) - assert 'txHash' in response - assert response['txHash'] == TX_HASH[2:] - assert isinstance(response['txHash'], str) - assert 'licenseTermsId' in response - assert response['licenseTermsId'] == 1 + assert 'tx_hash' in response + assert response['tx_hash'] == TX_HASH[2:] + assert isinstance(response['tx_hash'], str) + assert 'license_terms_id' in response + assert response['license_terms_id'] == 1 - def test_registerCommercialUsePIL_error(self, license_client): + def test_register_commercial_use_pil_error(self, license_client): with patch.object(license_client.license_template_client, 'getLicenseTermsId', return_value=0), \ patch.object(license_client.license_terms_util.royalty_module_client, 'isWhitelistedRoyaltyPolicy', return_value=True), \ patch.object(license_client.license_template_client, 'build_registerLicenseTerms_transaction', side_effect=Exception("request fail.")): with pytest.raises(Exception, match="request fail."): - license_client.registerCommercialUsePIL( + license_client.register_commercial_use_pil( default_minting_fee=1, currency=ZERO_ADDRESS ) @@ -272,19 +272,19 @@ def test_registerCommercialUsePIL_error(self, license_client): class TestCommercialRemixPIL: """Tests for commercial remix PIL functionality.""" - def test_registerCommercialRemixPIL_license_terms_id_registered(self, license_client): + def test_register_commercial_remix_pil_license_terms_id_registered(self, license_client): with patch.object(license_client.license_template_client, 'getLicenseTermsId', return_value=1), \ patch.object(license_client.license_terms_util.royalty_module_client, 'isWhitelistedRoyaltyPolicy', return_value=True): - response = license_client.registerCommercialRemixPIL( + response = license_client.register_commercial_remix_pil( default_minting_fee=1, commercial_rev_share=100, currency=ZERO_ADDRESS, royalty_policy=ZERO_ADDRESS ) - assert response['licenseTermsId'] == 1 - assert 'txHash' not in response + assert response['license_terms_id'] == 1 + assert 'tx_hash' not in response - def test_registerCommercialRemixPIL_success(self, license_client, mock_signed_txn, mock_account): + def test_register_commercial_remix_pil_success(self, license_client, mock_signed_txn, mock_account): with patch.object(license_client.license_template_client, 'getLicenseTermsId', return_value=0), \ patch.object(license_client.license_terms_util.royalty_module_client, 'isWhitelistedRoyaltyPolicy', return_value=True), \ patch.object(license_client.license_template_client, 'build_registerLicenseTerms_transaction', @@ -295,52 +295,52 @@ def test_registerCommercialRemixPIL_success(self, license_client, mock_signed_tx patch.object(license_client.web3.eth, 'wait_for_transaction_receipt', return_value=MagicMock()), \ patch.object(license_client, '_parse_tx_license_terms_registered_event', return_value=1): - response = license_client.registerCommercialRemixPIL( + response = license_client.register_commercial_remix_pil( default_minting_fee=1, commercial_rev_share=100, currency=ZERO_ADDRESS, royalty_policy=ZERO_ADDRESS ) - assert 'txHash' in response - assert response['txHash'] == TX_HASH[2:] - assert isinstance(response['txHash'], str) - assert response['licenseTermsId'] == 1 + assert 'tx_hash' in response + assert response['tx_hash'] == TX_HASH[2:] + assert isinstance(response['tx_hash'], str) + assert response['license_terms_id'] == 1 class TestLicenseAttachment: """Tests for license attachment functionality.""" - def test_attachLicenseTerms_ip_not_registered(self, license_client): + def test_attach_license_terms_ip_not_registered(self, license_client): with patch.object(license_client.ip_asset_registry_client, 'isRegistered', return_value=False): with pytest.raises(ValueError, match=f'The IP with id {ZERO_ADDRESS} is not registered.'): - license_client.attachLicenseTerms( + license_client.attach_license_terms( ip_id=ZERO_ADDRESS, license_template=ZERO_ADDRESS, license_terms_id=1 ) - def test_attachLicenseTerms_license_terms_not_exist(self, license_client): + def test_attach_license_terms_license_terms_not_exist(self, license_client): with patch.object(license_client.ip_asset_registry_client, 'isRegistered', return_value=True), \ patch.object(license_client.license_registry_client, 'exists', return_value=False): with pytest.raises(ValueError, match='License terms id 1 do not exist.'): - license_client.attachLicenseTerms( + license_client.attach_license_terms( ip_id=ZERO_ADDRESS, license_template=ZERO_ADDRESS, license_terms_id=1 ) - def test_attachLicenseTerms_already_attached(self, license_client): + def test_attach_license_terms_already_attached(self, license_client): with patch.object(license_client.ip_asset_registry_client, 'isRegistered', return_value=True), \ patch.object(license_client.license_registry_client, 'exists', return_value=True), \ patch.object(license_client.license_registry_client, 'hasIpAttachedLicenseTerms', return_value=True): with pytest.raises(ValueError, match=f'License terms id 1 is already attached to the IP with id {ZERO_ADDRESS}.'): - license_client.attachLicenseTerms( + license_client.attach_license_terms( ip_id=ZERO_ADDRESS, license_template=ZERO_ADDRESS, license_terms_id=1 ) - def test_attachLicenseTerms_success(self, license_client, mock_signed_txn, mock_account): + def test_attach_license_terms_success(self, license_client, mock_signed_txn, mock_account): with patch.object(license_client.ip_asset_registry_client, 'isRegistered', return_value=True), \ patch.object(license_client.license_registry_client, 'exists', return_value=True), \ patch.object(license_client.license_registry_client, 'hasIpAttachedLicenseTerms', return_value=False), \ @@ -352,23 +352,23 @@ def test_attachLicenseTerms_success(self, license_client, mock_signed_txn, mock_ patch.object(license_client.web3.eth, 'wait_for_transaction_receipt', return_value=MagicMock()), \ patch.object(license_client, '_parse_tx_license_terms_registered_event', return_value=1): - response = license_client.attachLicenseTerms( + response = license_client.attach_license_terms( ip_id=ZERO_ADDRESS, license_template=ZERO_ADDRESS, license_terms_id=1 ) - assert 'txHash' in response - assert response['txHash'] == TX_HASH[2:] - assert isinstance(response['txHash'], str) + assert 'tx_hash' in response + assert response['tx_hash'] == TX_HASH[2:] + assert isinstance(response['tx_hash'], str) class TestLicenseTokens: """Tests for license token minting functionality.""" - def test_mintLicenseTokens_licensor_ip_not_registered(self, license_client): + def test_mint_license_tokens_licensor_ip_not_registered(self, license_client): with patch.object(license_client.ip_asset_registry_client, 'isRegistered', return_value=False): with pytest.raises(ValueError, match=f"The licensor IP with id {ZERO_ADDRESS} is not registered."): - license_client.mintLicenseTokens( + license_client.mint_license_tokens( licensor_ip_id=ZERO_ADDRESS, license_template=ZERO_ADDRESS, license_terms_id=1, @@ -376,11 +376,11 @@ def test_mintLicenseTokens_licensor_ip_not_registered(self, license_client): receiver=ZERO_ADDRESS ) - def test_mintLicenseTokens_license_terms_not_exist(self, license_client): + def test_mint_license_tokens_license_terms_not_exist(self, license_client): with patch.object(license_client.ip_asset_registry_client, 'isRegistered', return_value=True), \ patch.object(license_client.license_template_client, 'exists', return_value=False): with pytest.raises(ValueError, match='License terms id 1 do not exist.'): - license_client.mintLicenseTokens( + license_client.mint_license_tokens( licensor_ip_id=ZERO_ADDRESS, license_template=ZERO_ADDRESS, license_terms_id=1, @@ -388,13 +388,13 @@ def test_mintLicenseTokens_license_terms_not_exist(self, license_client): receiver=ZERO_ADDRESS ) - def test_mintLicenseTokens_not_attached(self, license_client): + def test_mint_license_tokens_not_attached(self, license_client): with patch.object(license_client.ip_asset_registry_client, 'isRegistered', return_value=True), \ patch.object(license_client.license_template_client, 'exists', return_value=True), \ patch.object(license_client.license_registry_client, 'hasIpAttachedLicenseTerms', return_value=False): with pytest.raises(ValueError, match=f'License terms id 1 is not attached to the IP with id {ZERO_ADDRESS}.'): - license_client.mintLicenseTokens( + license_client.mint_license_tokens( licensor_ip_id=ZERO_ADDRESS, license_template=ZERO_ADDRESS, license_terms_id=1, @@ -402,10 +402,10 @@ def test_mintLicenseTokens_not_attached(self, license_client): receiver=ZERO_ADDRESS ) - def test_mintLicenseTokens_invalid_template(self, license_client): + def test_mint_license_tokens_invalid_template(self, license_client): with patch.object(license_client.ip_asset_registry_client, 'isRegistered', return_value=True): with pytest.raises(ValueError, match='Address "invalid address" is invalid'): - license_client.mintLicenseTokens( + license_client.mint_license_tokens( licensor_ip_id=ZERO_ADDRESS, license_template="invalid address", license_terms_id=1, @@ -413,10 +413,10 @@ def test_mintLicenseTokens_invalid_template(self, license_client): receiver=ZERO_ADDRESS ) - def test_mintLicenseTokens_invalid_receiver(self, license_client): + def test_mint_license_tokens_invalid_receiver(self, license_client): with patch.object(license_client.ip_asset_registry_client, 'isRegistered', return_value=True): with pytest.raises(ValueError, match='Address "invalid address" is invalid'): - license_client.mintLicenseTokens( + license_client.mint_license_tokens( licensor_ip_id=ZERO_ADDRESS, license_template=ZERO_ADDRESS, license_terms_id=1, @@ -424,7 +424,7 @@ def test_mintLicenseTokens_invalid_receiver(self, license_client): receiver="invalid address" ) - def test_mintLicenseTokens_success(self, license_client, mock_signed_txn, mock_account): + def test_mint_license_tokens_success(self, license_client, mock_signed_txn, mock_account): with patch.object(license_client.ip_asset_registry_client, 'isRegistered', return_value=True), \ patch.object(license_client.license_template_client, 'exists', return_value=True), \ patch.object(license_client.license_registry_client, 'hasIpAttachedLicenseTerms', return_value=True), \ @@ -435,7 +435,7 @@ def test_mintLicenseTokens_success(self, license_client, mock_signed_txn, mock_a patch.object(license_client.web3.eth, 'wait_for_transaction_receipt', return_value=MagicMock()), \ patch.object(license_client, '_parse_tx_license_terms_registered_event', return_value=1): - response = license_client.mintLicenseTokens( + response = license_client.mint_license_tokens( licensor_ip_id=ZERO_ADDRESS, license_template=ZERO_ADDRESS, license_terms_id=1, @@ -443,14 +443,14 @@ def test_mintLicenseTokens_success(self, license_client, mock_signed_txn, mock_a receiver=ZERO_ADDRESS ) - assert 'txHash' in response - assert response['txHash'] == TX_HASH[2:] - assert isinstance(response['txHash'], str) + assert 'tx_hash' in response + assert response['tx_hash'] == TX_HASH[2:] + assert isinstance(response['tx_hash'], str) class TestLicenseTerms: """Tests for retrieving license terms.""" - def test_getLicenseTerms_success(self, license_client): + def test_get_license_terms_success(self, license_client): mock_response = { 'terms': { 'transferable': True, @@ -473,31 +473,31 @@ def test_getLicenseTerms_success(self, license_client): } } with patch.object(license_client.license_template_client, 'getLicenseTerms', return_value=mock_response): - response = license_client.getLicenseTerms(1) + response = license_client.get_license_terms(1) assert response == mock_response - def test_getLicenseTerms_not_exist(self, license_client): + def test_get_license_terms_not_exist(self, license_client): with patch.object(license_client.license_template_client, 'getLicenseTerms', side_effect=Exception("Given licenseTermsId is not exist.")): with pytest.raises(ValueError, match="Failed to get license terms: Given licenseTermsId is not exist."): - license_client.getLicenseTerms(1) + license_client.get_license_terms(1) class TestLicensingConfig: """Tests for license configuration functionality.""" - def test_setLicensingConfig_missing_params(self, license_client): + def test_set_licensing_config_missing_params(self, license_client): incomplete_config = { 'isSet': True, 'mintingFee': 0, } with pytest.raises(ValueError, match="Missing required licensing_config parameters:"): - license_client.setLicensingConfig( + license_client.set_licensing_config( ip_id=ZERO_ADDRESS, license_terms_id=1, licensing_config=incomplete_config ) - def test_setLicensingConfig_negative_minting_fee(self, license_client): + def test_set_licensing_config_negative_minting_fee(self, license_client): config = { 'isSet': True, 'mintingFee': -1, @@ -509,13 +509,13 @@ def test_setLicensingConfig_negative_minting_fee(self, license_client): 'expectGroupRewardPool': ZERO_ADDRESS } with pytest.raises(ValueError, match="Failed to set licensing config: The minting fee must be greater than 0."): - license_client.setLicensingConfig( + license_client.set_licensing_config( ip_id=ZERO_ADDRESS, license_terms_id=1, licensing_config=config ) - def test_setLicensingConfig_unregistered_licensing_hook(self, license_client): + def test_set_licensing_config_unregistered_licensing_hook(self, license_client): custom_address = "0x1234567890123456789012345678901234567890" config = { 'isSet': True, @@ -530,13 +530,13 @@ def test_setLicensingConfig_unregistered_licensing_hook(self, license_client): with patch.object(license_client.ip_asset_registry_client, 'isRegistered', return_value=True), \ patch.object(license_client.module_registry_client, 'isRegistered', return_value=False): with pytest.raises(ValueError, match="Failed to set licensing config: The licensing hook is not registered."): - license_client.setLicensingConfig( + license_client.set_licensing_config( ip_id=ZERO_ADDRESS, license_terms_id=1, licensing_config=config ) - def test_setLicensingConfig_template_terms_mismatch(self, license_client): + def test_set_licensing_config_template_terms_mismatch(self, license_client): config = { 'isSet': True, 'mintingFee': 1, @@ -549,14 +549,14 @@ def test_setLicensingConfig_template_terms_mismatch(self, license_client): } with patch.object(license_client.ip_asset_registry_client, 'isRegistered', return_value=True): with pytest.raises(ValueError, match="Failed to set licensing config: The license template is zero address but license terms id is not zero."): - license_client.setLicensingConfig( + license_client.set_licensing_config( ip_id=ZERO_ADDRESS, license_terms_id=1, license_template=ZERO_ADDRESS, licensing_config=config ) - def test_setLicensingConfig_zero_address_with_rev_share(self, license_client): + def test_set_licensing_config_zero_address_with_rev_share(self, license_client): config = { 'isSet': True, 'mintingFee': 1, @@ -569,7 +569,7 @@ def test_setLicensingConfig_zero_address_with_rev_share(self, license_client): } with patch.object(license_client.ip_asset_registry_client, 'isRegistered', return_value=True): with pytest.raises(ValueError, match="Failed to set licensing config: The license template cannot be zero address if commercial revenue share is not zero."): - license_client.setLicensingConfig( + license_client.set_licensing_config( ip_id=ZERO_ADDRESS, license_terms_id=0, license_template=ZERO_ADDRESS, diff --git a/tests/unit/resources/test_royalty.py b/tests/unit/resources/test_royalty.py index 51d7fd5..767d82b 100644 --- a/tests/unit/resources/test_royalty.py +++ b/tests/unit/resources/test_royalty.py @@ -28,185 +28,30 @@ @pytest.fixture def royalty_client(): - chain_id = 11155111 # Sepolia chain ID + chain_id = 1315 return Royalty(web3, account, chain_id) -def test_collectRoyaltyTokens_parent_ip_id_not_registered(royalty_client): - parent_ip_id = "0xA34611b0E11Bba2b11c69864f7D36aC83D862A9c" - child_ip_id = "0x9C098DF37b2324aaC8792dDc7BcEF7Bb0057A9C7" - - with patch.object(royalty_client.ip_asset_registry_client, 'isRegistered', return_value=False, autospec=True): - with pytest.raises(ValueError) as excinfo: - royalty_client.collectRoyaltyTokens(parent_ip_id, child_ip_id) - assert str(excinfo.value) == f"The parent IP with id {parent_ip_id} is not registered." - -def test_collectRoyaltyTokens_royalty_vault_ip_id_not_registered(royalty_client): - parent_ip_id = "0xA34611b0E11Bba2b11c69864f7D36aC83D862A9c" - child_ip_id = "0x9C098DF37b2324aaC8792dDc7BcEF7Bb0057A9C7" - - with patch.object(royalty_client.ip_asset_registry_client, 'isRegistered', side_effect=[True, False], autospec=True): - with pytest.raises(ValueError) as excinfo: - royalty_client.collectRoyaltyTokens(parent_ip_id, child_ip_id) - assert str(excinfo.value) == f"The IP with id {child_ip_id} is not registered." - -def test_collectRoyaltyTokens_royalty_vault_address_empty(royalty_client): - parent_ip_id = "0xA34611b0E11Bba2b11c69864f7D36aC83D862A9c" - child_ip_id = "0x9C098DF37b2324aaC8792dDc7BcEF7Bb0057A9C7" - - with patch.object(royalty_client.ip_asset_registry_client, 'isRegistered', return_value=True, autospec=True), \ - patch.object(royalty_client.royalty_policy_lap_client, 'getRoyaltyData', return_value=[], autospec=True): - with pytest.raises(ValueError) as excinfo: - royalty_client.collectRoyaltyTokens(parent_ip_id, child_ip_id) - assert str(excinfo.value) == f"The royalty vault IP with id {child_ip_id} address is not set." - -def test_collectRoyaltyTokens_royalty_vault_address_zero(royalty_client): - parent_ip_id = "0xA34611b0E11Bba2b11c69864f7D36aC83D862A9c" - child_ip_id = "0x9C098DF37b2324aaC8792dDc7BcEF7Bb0057A9C7" - - with patch.object(royalty_client.ip_asset_registry_client, 'isRegistered', return_value=True, autospec=True), \ - patch.object(royalty_client.royalty_policy_lap_client, 'getRoyaltyData', return_value=[True, "0x", 1, [child_ip_id], [1]], autospec=True): - with pytest.raises(ValueError) as excinfo: - royalty_client.collectRoyaltyTokens(parent_ip_id, child_ip_id) - assert str(excinfo.value) == f"The royalty vault IP with id {child_ip_id} address is not set." - -def test_collectRoyaltyTokens_success(royalty_client): - parent_ip_id = "0xA34611b0E11Bba2b11c69864f7D36aC83D862A9c" - child_ip_id = "0x9C098DF37b2324aaC8792dDc7BcEF7Bb0057A9C7" - tx_hash = "0x39f7ea8b04f383d7b60e1882f6bb7d94d3c9efa9251cef4543a1bb655faf21fb" - checksum_address = "0x344A37c7086Ee79E51894949119878112487eaD7" - royalty_tokens_collected = 10 - - # Mocking the expected behavior of the functions - with patch.object(royalty_client.ip_asset_registry_client, 'isRegistered', return_value=True), \ - patch.object(royalty_client, '_getRoyaltyVaultAddress', return_value=checksum_address), \ - patch.object(royalty_client, '_parseTxRoyaltyTokensCollectedEvent', return_value=royalty_tokens_collected), \ - patch('story_protocol_python_sdk.abi.IpRoyaltyVaultImpl.IpRoyaltyVaultImpl_client.IpRoyaltyVaultImplClient.build_collectRoyaltyTokens_transaction', return_value={ - 'data': '0x', - 'nonce': 0, - 'gas': 2000000, - 'gasPrice': Web3.to_wei('300', 'gwei') - }), \ - patch('web3.eth.Eth.send_raw_transaction', return_value=Web3.to_bytes(hexstr=tx_hash)), \ - patch('web3.eth.Eth.wait_for_transaction_receipt', return_value={'status': 1, 'logs': [{'topics': [Web3.keccak(text="RoyaltyTokensCollected(address,uint256)").hex()], 'data': bytes.fromhex('000000000000000000000000000000000000000000000000000000000000000a')}]}): - - # Call the function being tested - result = royalty_client.collectRoyaltyTokens(parent_ip_id, child_ip_id) - - assert result['txHash'] == tx_hash[2:] - assert result['royaltyTokensCollected'] == royalty_tokens_collected - -def test_snapshot_royaltyVaultIpId_error(royalty_client): - with patch.object(royalty_client.ip_asset_registry_client, 'isRegistered', return_value=False): - child_ip_id = "0xA34611b0E11Bba2b11c69864f7D36aC83D862A9c" - - with pytest.raises(ValueError, match=f"The IP with id {child_ip_id} is not registered."): - royalty_client.snapshot(child_ip_id=child_ip_id) - -def test_snapshot_royaltyVaultAddress_error(royalty_client): - with patch.object(royalty_client.ip_asset_registry_client, 'isRegistered', return_value=True): - with patch.object(royalty_client.royalty_policy_lap_client, 'getRoyaltyData', return_value=[True, "0x", 1, ["0xA34611b0E11Bba2b11c69864f7D36aC83D862A9c"], [1]]): - child_ip_id = "0xA34611b0E11Bba2b11c69864f7D36aC83D862A9c" - - with pytest.raises(ValueError, match=f"The royalty vault IP with id {child_ip_id} address is not set."): - royalty_client.snapshot(child_ip_id=child_ip_id) - -def test_snapshot_success(royalty_client): - with patch.object(royalty_client.ip_asset_registry_client, 'isRegistered', return_value=True): - with patch.object(royalty_client.royalty_policy_lap_client, 'getRoyaltyData', return_value=[True, "0xA34611b0E11Bba2b11c69864f7D36aC83D862A9c", 1, ["0xA34611b0E11Bba2b11c69864f7D36aC83D862A9c"], [1]]): - with patch.object(royalty_client, '_parseTxSnapshotCompletedEvent', return_value=2): - with patch('story_protocol_python_sdk.abi.IpRoyaltyVaultImpl.IpRoyaltyVaultImpl_client.IpRoyaltyVaultImplClient.build_snapshot_transaction', return_value={ - 'data': '0x', - 'nonce': 0, - 'gas': 2000000, - 'gasPrice': Web3.to_wei('300', 'gwei') - }): - with patch('web3.eth.Eth.send_raw_transaction', return_value=Web3.to_bytes(hexstr='0x471343c1ad3b358843b2079d8c5c1a0a5a86fe88382cdc67604b0209bbedf523')): - with patch('web3.eth.Eth.wait_for_transaction_receipt', return_value={'status': 1, 'logs': []}): - child_ip_id = "0xA34611b0E11Bba2b11c69864f7D36aC83D862A9c" - - response = royalty_client.snapshot(child_ip_id=child_ip_id) - assert response is not None - assert 'txHash' in response - assert response['txHash'] == '471343c1ad3b358843b2079d8c5c1a0a5a86fe88382cdc67604b0209bbedf523' - assert 'snapshotId' in response - assert response['snapshotId'] == 2 - -def test_claimableRevenue_royaltyVaultIpId_error(royalty_client): +def test_claimable_revenue_royalty_vault_ip_id_error(royalty_client): with patch.object(royalty_client.ip_asset_registry_client, 'isRegistered', return_value=False): child_ip_id = "0xA34611b0E11Bba2b11c69864f7D36aC83D862A9c" account_address = account.address - snapshot_id = 1 token = "0xB132A6B7AE652c974EE1557A3521D53d18F6739f" with pytest.raises(ValueError, match=f"The IP with id {child_ip_id} is not registered."): - royalty_client.claimableRevenue(child_ip_id, account_address, snapshot_id, token) + royalty_client.claimable_revenue(child_ip_id, account_address, token) -def test_claimableRevenue_royaltyVaultAddress_error(royalty_client): +def test_claimable_revenue_success(royalty_client): with patch.object(royalty_client.ip_asset_registry_client, 'isRegistered', return_value=True): - with patch.object(royalty_client.royalty_policy_lap_client, 'getRoyaltyData', return_value=[True, "0x", 1, ["0xA34611b0E11Bba2b11c69864f7D36aC83D862A9c"], [1]]): - parent_ip_id = "0xA34611b0E11Bba2b11c69864f7D36aC83D862A9c" - account_address = account.address - snapshot_id = 1 - token = "0xB132A6B7AE652c974EE1557A3521D53d18F6739f" - - with pytest.raises(ValueError, match=f"The royalty vault IP with id {parent_ip_id} address is not set."): - royalty_client.claimableRevenue(parent_ip_id, account_address, snapshot_id, token) - -def test_claimableRevenue_success(royalty_client): - with patch.object(royalty_client.ip_asset_registry_client, 'isRegistered', return_value=True): - with patch.object(royalty_client.royalty_policy_lap_client, 'getRoyaltyData', return_value=[True, "0xA34611b0E11Bba2b11c69864f7D36aC83D862A9c", 1, ["0xA34611b0E11Bba2b11c69864f7D36aC83D862A9c"], [1]]): + with patch.object(royalty_client, 'get_royalty_vault_address', return_value="0xA34611b0E11Bba2b11c69864f7D36aC83D862A9c"): with patch('story_protocol_python_sdk.abi.IpRoyaltyVaultImpl.IpRoyaltyVaultImpl_client.IpRoyaltyVaultImplClient.claimableRevenue', return_value=0): parent_ip_id = "0xA34611b0E11Bba2b11c69864f7D36aC83D862A9c" account_address = account.address - snapshot_id = 1 token = "0xB132A6B7AE652c974EE1557A3521D53d18F6739f" - response = royalty_client.claimableRevenue(parent_ip_id, account_address, snapshot_id, token) + response = royalty_client.claimable_revenue(parent_ip_id, account_address, token) assert response == 0 -def test_claimRevenue_royaltyVaultIpId_error(royalty_client): - with patch.object(royalty_client.ip_asset_registry_client, 'isRegistered', return_value=False): - parent_ip_id = "0x9C098DF37b2324aaC8792dDc7BcEF7Bb0057A9C7" - ERC20 = "0xB132A6B7AE652c974EE1557A3521D53d18F6739f" - snapshot_ids = [1, 2] - - with pytest.raises(ValueError, match=f"The IP with id {parent_ip_id} is not registered."): - royalty_client.claimRevenue(snapshot_ids, parent_ip_id, ERC20) - -def test_claimRevenue_royaltyVaultAddress_error(royalty_client): - with patch.object(royalty_client.ip_asset_registry_client, 'isRegistered', return_value=True): - with patch.object(royalty_client.royalty_policy_lap_client, 'getRoyaltyData', return_value=[True, "0x", 1, ["0x9C098DF37b2324aaC8792dDc7BcEF7Bb0057A9C7"], [1]]): - parent_ip_id = "0x9C098DF37b2324aaC8792dDc7BcEF7Bb0057A9C7" - ERC20 = "0xB132A6B7AE652c974EE1557A3521D53d18F6739f" - snapshot_ids = [1, 2] - - with pytest.raises(ValueError, match=f"The royalty vault IP with id {parent_ip_id} address is not set."): - royalty_client.claimRevenue(snapshot_ids, parent_ip_id, ERC20) - -def test_claimRevenue_success(royalty_client): - with patch.object(royalty_client.ip_asset_registry_client, 'isRegistered', return_value=True): - with patch.object(royalty_client.royalty_policy_lap_client, 'getRoyaltyData', return_value=[True, "0x9C098DF37b2324aaC8792dDc7BcEF7Bb0057A9C7", 1, ["0x9C098DF37b2324aaC8792dDc7BcEF7Bb0057A9C7"], [1]]): - with patch.object(royalty_client, '_parseTxRevenueTokenClaimedEvent', return_value=0): - with patch('story_protocol_python_sdk.abi.IpRoyaltyVaultImpl.IpRoyaltyVaultImpl_client.IpRoyaltyVaultImplClient.build_claimRevenueBySnapshotBatch_transaction', return_value={ - 'data': '0x', - 'nonce': 0, - 'gas': 2000000, - 'gasPrice': Web3.to_wei('300', 'gwei') - }): - with patch('web3.eth.Eth.send_raw_transaction', return_value=Web3.to_bytes(hexstr='0x7065317271b179a2b4d47ff23b9b12ea50cdf668b892c8912cd7df71797b6561')): - with patch('web3.eth.Eth.wait_for_transaction_receipt', return_value={'status': 1, 'logs': []}): - parent_ip_id = "0x9C098DF37b2324aaC8792dDc7BcEF7Bb0057A9C7" - ERC20 = "0xB132A6B7AE652c974EE1557A3521D53d18F6739f" - snapshot_ids = [1, 2] - - response = royalty_client.claimRevenue(snapshot_ids, parent_ip_id, ERC20) - assert response is not None - assert 'txHash' in response - assert response['txHash'] == '7065317271b179a2b4d47ff23b9b12ea50cdf668b892c8912cd7df71797b6561' - assert 'claimableToken' in response - assert response['claimableToken'] == 0 - -def test_payRoyaltyOnBehalf_receiverIpId_error(royalty_client): +def test_pay_royalty_on_behalf_receiver_ip_id_error(royalty_client): with patch.object(royalty_client.ip_asset_registry_client, 'isRegistered', return_value=False): receiver_ip_id = "0xA34611b0E11Bba2b11c69864f7D36aC83D862A9c" payer_ip_id = "0x9C098DF37b2324aaC8792dDc7BcEF7Bb0057A9C7" @@ -214,9 +59,9 @@ def test_payRoyaltyOnBehalf_receiverIpId_error(royalty_client): amount = 1 with pytest.raises(ValueError, match=f"The receiver IP with id {receiver_ip_id} is not registered."): - royalty_client.payRoyaltyOnBehalf(receiver_ip_id, payer_ip_id, ERC20, amount) + royalty_client.pay_royalty_on_behalf(receiver_ip_id, payer_ip_id, ERC20, amount) -def test_payRoyaltyOnBehalf_payerIpId_error(royalty_client): +def test_pay_royalty_on_behalf_payer_ip_id_error(royalty_client): with patch.object(royalty_client.ip_asset_registry_client, 'isRegistered', side_effect=[True, False]): receiver_ip_id = "0xA34611b0E11Bba2b11c69864f7D36aC83D862A9c" payer_ip_id = "0x9C098DF37b2324aaC8792dDc7BcEF7Bb0057A9C7" @@ -224,9 +69,9 @@ def test_payRoyaltyOnBehalf_payerIpId_error(royalty_client): amount = 1 with pytest.raises(ValueError, match=f"The payer IP with id {payer_ip_id} is not registered."): - royalty_client.payRoyaltyOnBehalf(receiver_ip_id, payer_ip_id, ERC20, amount) + royalty_client.pay_royalty_on_behalf(receiver_ip_id, payer_ip_id, ERC20, amount) -def test_payRoyaltyOnBehalf_success(royalty_client): +def test_pay_royalty_on_behalf_success(royalty_client): with patch.object(royalty_client.ip_asset_registry_client, 'isRegistered', return_value=True): with patch('story_protocol_python_sdk.abi.RoyaltyModule.RoyaltyModule_client.RoyaltyModuleClient.build_payRoyaltyOnBehalf_transaction', return_value={ 'data': '0x', @@ -241,7 +86,7 @@ def test_payRoyaltyOnBehalf_success(royalty_client): ERC20 = "0xB132A6B7AE652c974EE1557A3521D53d18F6739f" amount = 1 - response = royalty_client.payRoyaltyOnBehalf(receiver_ip_id, payer_ip_id, ERC20, amount, tx_options={'wait_for_transaction': True}) + response = royalty_client.pay_royalty_on_behalf(receiver_ip_id, payer_ip_id, ERC20, amount, tx_options={'wait_for_transaction': True}) assert response is not None - assert 'txHash' in response - assert response['txHash'] == 'badf64f2c220e27407c4d2ccbc772fb72c7dc590ac25000dc316e4dc519fbfa2' + assert 'tx_hash' in response + assert response['tx_hash'] == 'badf64f2c220e27407c4d2ccbc772fb72c7dc590ac25000dc316e4dc519fbfa2'