From 37dae0fb4e80c8e6ab682e23011f91e827ec822e Mon Sep 17 00:00:00 2001 From: Andy Wu Date: Fri, 1 Aug 2025 17:16:06 -0700 Subject: [PATCH 01/12] feat: enhance pre-commit configuration with comprehensive hooks - Add comprehensive pre-commit hooks for better code quality - trailing-whitespace: Remove trailing whitespace - end-of-file-fixer: Ensure files end with newline - check-added-large-files: Prevent large files from being committed - check-json: Validate JSON files - check-toml: Validate TOML files - debug-statements: Check for debugger imports - mixed-line-ending: Normalize line endings - isort: Sort imports with black-compatible profile - ruff: Fast Python linter with auto-fix capabilities - Update .gitignore to exclude CLAUDE.md (AI assistant configuration file) - Maintain existing black formatter configuration --- .gitignore | 5 ++++- .pre-commit-config.yaml | 31 ++++++++++++++++++++++++++----- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index efbdec4..bcc2d92 100644 --- a/.gitignore +++ b/.gitignore @@ -103,4 +103,7 @@ celerybeat.pid # Environments .env -web3py.md \ No newline at end of file +web3py.md + +# AI Assistant Configuration +CLAUDE.md \ No newline at end of file diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3bd9e35..42144bb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,12 +1,33 @@ +# See https://pre-commit.com for more information +# See https://pre-commit.com/hooks.html for more hooks repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-added-large-files + - id: check-json + - id: check-merge-conflict + - id: check-toml + - id: debug-statements + - id: mixed-line-ending + - repo: https://github.com/psf/black - rev: 25.1.0 + rev: 23.12.1 hooks: - id: black language_version: python3 - - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v5.0.0 + - repo: https://github.com/pycqa/isort + rev: 5.13.2 hooks: - - id: check-yaml - - id: check-merge-conflict + - id: isort + args: ["--profile", "black"] + + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.1.9 + hooks: + - id: ruff + args: [--fix, --exit-non-zero-on-fix, --unsafe-fixes] \ No newline at end of file From e34eeb907fefb578554d1536d7602314d47ab663 Mon Sep 17 00:00:00 2001 From: Andy Wu Date: Fri, 1 Aug 2025 17:19:49 -0700 Subject: [PATCH 02/12] docs: add comprehensive development guide with uv package manager - Create DEVELOPMENT.md with detailed setup instructions - Add uv installation guide for all platforms - Document all pre-commit hooks and their purposes - Include troubleshooting section for common issues - Update README.md to reference the new development guide - Provide clear workflow instructions for testing and formatting --- DEVELOPMENT.md | 220 +++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 6 +- 2 files changed, 222 insertions(+), 4 deletions(-) create mode 100644 DEVELOPMENT.md diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md new file mode 100644 index 0000000..69eafac --- /dev/null +++ b/DEVELOPMENT.md @@ -0,0 +1,220 @@ +# Development Guide + +This guide provides instructions for setting up the development environment for the Story Protocol Python SDK. + +## Prerequisites + +- Python 3.10 or higher +- Git +- [uv](https://github.com/astral-sh/uv) - Fast Python package installer and resolver + +## Installing uv + +uv is a fast Python package installer and resolver written in Rust. It's a drop-in replacement for pip and pip-tools. + +### macOS/Linux +```bash +curl -LsSf https://astral.sh/uv/install.sh | sh +``` + +### Windows +```powershell +powershell -c "irm https://astral.sh/uv/install.ps1 | iex" +``` + +### Alternative: Install via pip +```bash +pip install uv +``` + +## Setting Up the Development Environment + +### 1. Clone the repository +```bash +git clone https://github.com/storyprotocol/python-sdk.git +cd python-sdk +``` + +### 2. Create and activate a virtual environment with uv +```bash +# Create a virtual environment +uv venv + +# Activate the virtual environment +# On macOS/Linux: +source .venv/bin/activate +# On Windows: +.venv\Scripts\activate +``` + +### 3. Install dependencies with uv +```bash +# Install the package in editable mode with all dependencies +uv pip install -e . + +# Install additional development dependencies +uv pip install pytest pytest-cov black isort ruff pre-commit python-dotenv +``` + +### 4. Set up pre-commit hooks +```bash +# Install pre-commit hooks +pre-commit install + +# Run pre-commit on all files to ensure everything is set up correctly +pre-commit run --all-files +``` + +## Development Workflow + +### Running Tests + +```bash +# Run all integration tests (default) +pytest + +# Run unit tests with coverage +coverage run -m pytest tests/unit -v -ra -q +coverage report + +# Run specific test file +pytest tests/integration/test_integration_ip_asset.py -v + +# Run tests with specific markers +pytest -m integration # Run only integration tests +pytest -m unit # Run only unit tests +``` + +### Code Formatting and Linting + +The project uses several tools to maintain code quality: + +1. **Black** - Code formatter + ```bash + black . + ``` + +2. **isort** - Import sorter + ```bash + isort . --profile black + ``` + +3. **Ruff** - Fast Python linter + ```bash + ruff check . --fix + ``` + +All these tools are automatically run as pre-commit hooks when you commit code. + +### Manual Pre-commit Checks + +To manually run all pre-commit checks: +```bash +pre-commit run --all-files +``` + +To run a specific hook: +```bash +pre-commit run black --all-files +pre-commit run ruff --all-files +``` + +## Pre-commit Hooks Overview + +The project uses the following pre-commit hooks: + +| Hook | Purpose | +|------|---------| +| `trailing-whitespace` | Removes trailing whitespace | +| `end-of-file-fixer` | Ensures files end with a newline | +| `check-yaml` | Validates YAML syntax | +| `check-added-large-files` | Prevents large files from being committed | +| `check-json` | Validates JSON syntax | +| `check-merge-conflict` | Checks for merge conflict markers | +| `check-toml` | Validates TOML syntax | +| `debug-statements` | Checks for debugger imports | +| `mixed-line-ending` | Normalizes line endings | +| `black` | Formats Python code | +| `isort` | Sorts Python imports | +| `ruff` | Lints Python code and auto-fixes issues | + +## Updating Dependencies with uv + +### Add a new dependency +```bash +# Add to setup.py's install_requires, then: +uv pip install -e . +``` + +### Upgrade dependencies +```bash +# Upgrade specific package +uv pip install --upgrade package-name + +# Upgrade all packages +uv pip install --upgrade -e . +``` + +### Speed Comparison + +uv is significantly faster than pip: +- **Installation**: 10-100x faster than pip +- **Resolution**: More efficient dependency resolver +- **Caching**: Better cache utilization + +## Environment Variables + +Create a `.env` file in the project root for local development: +```env +WALLET_PRIVATE_KEY=your_private_key_here +RPC_PROVIDER_URL=https://aeneid.storyrpc.io +``` + +## Troubleshooting + +### Pre-commit hooks failing + +1. Ensure all tools are installed: + ```bash + uv pip install black isort ruff pre-commit + ``` + +2. Update pre-commit hooks: + ```bash + pre-commit autoupdate + ``` + +3. Clear pre-commit cache: + ```bash + pre-commit clean + ``` + +### Import errors + +1. Ensure you're in the virtual environment: + ```bash + which python # Should point to .venv/bin/python + ``` + +2. Reinstall in editable mode: + ```bash + uv pip install -e . + ``` + +### uv installation issues + +If uv is not working properly: +1. Try installing via pip: `pip install uv` +2. Ensure it's in your PATH: `which uv` +3. On Windows, restart your terminal after installation + +## Contributing + +Before submitting a pull request: + +1. Ensure all tests pass: `pytest` +2. Run pre-commit checks: `pre-commit run --all-files` +3. Update tests if adding new functionality +4. Follow the existing code style and patterns + +See [CONTRIBUTING.md](CONTRIBUTING.md) for more details. \ No newline at end of file diff --git a/README.md b/README.md index 2650272..ed78373 100644 --- a/README.md +++ b/README.md @@ -58,11 +58,9 @@ aeneid_chain_id = 1315 story_client = StoryClient(web3, account, aeneid_chain_id) ``` -## Init pre-commit hooks +## Development -``` -pre-commit install -``` +For detailed development setup instructions, including how to install dependencies with `uv` and set up pre-commit hooks, see [DEVELOPMENT.md](DEVELOPMENT.md). ## Running test cases From 82a331c924ad2218d2f4a679a38bc1b4851978e9 Mon Sep 17 00:00:00 2001 From: Andy Wu Date: Fri, 1 Aug 2025 17:25:35 -0700 Subject: [PATCH 03/12] chore: update pre-commit hooks to latest versions - Update black from 23.12.1 to 25.1.0 - Update pre-commit-hooks from v4.5.0 to v5.0.0 - Update ruff from v0.1.9 to v0.8.4 - Keep isort at 5.13.2 (latest stable version) --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 42144bb..8cabf22 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ # See https://pre-commit.com/hooks.html for more hooks repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v5.0.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer @@ -15,7 +15,7 @@ repos: - id: mixed-line-ending - repo: https://github.com/psf/black - rev: 23.12.1 + rev: 25.1.0 hooks: - id: black language_version: python3 @@ -27,7 +27,7 @@ repos: args: ["--profile", "black"] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.1.9 + rev: v0.8.4 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix, --unsafe-fixes] \ No newline at end of file From a4648e0ad341b1dde54ef39c9c1ea96da010ba39 Mon Sep 17 00:00:00 2001 From: Andy Wu Date: Fri, 1 Aug 2025 17:29:10 -0700 Subject: [PATCH 04/12] fix: add virtual environment directories to .gitignore - Add venv/, env/, ENV/, .venv/, virtualenv/ to .gitignore - Prevents accidentally committing virtual environment files - Virtual environments should always be created locally - Reduces repository size and avoids platform-specific issues --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index bcc2d92..2eb8c78 100644 --- a/.gitignore +++ b/.gitignore @@ -102,6 +102,11 @@ celerybeat.pid # Environments .env +venv/ +env/ +ENV/ +.venv/ +virtualenv/ web3py.md From 7f1911171f7dec8a39d9cd5b8060d30022b0321e Mon Sep 17 00:00:00 2001 From: Bonnie Date: Mon, 4 Aug 2025 11:25:14 +0800 Subject: [PATCH 05/12] -mFix order and useless variables --- .coveragerc | 1 - .env-example | 2 +- .github/pull_request_template.md | 8 +-- .gitignore | 2 +- .pre-commit-config.yaml | 2 +- CODE_OF_CONDUCT.md | 2 +- CONTRIBUTING.md | 2 +- DEVELOPMENT.md | 2 +- MANIFEST.in | 2 +- pytest.ini | 2 +- src/story_protocol_python_sdk/__init__.py | 7 ++- .../AccessController_client.py | 3 +- .../ArbitrationPolicyUMA_client.py | 3 +- .../CoreMetadataModule_client.py | 3 +- .../CoreMetadataViewModule_client.py | 3 +- .../DerivativeWorkflows_client.py | 3 +- .../abi/DisputeModule/DisputeModule_client.py | 3 +- .../GroupingModule/GroupingModule_client.py | 3 +- .../GroupingWorkflows_client.py | 3 +- .../abi/IPAccountImpl/IPAccountImpl_client.py | 1 + .../IPAssetRegistry/IPAssetRegistry_client.py | 3 +- .../IpRoyaltyVaultImpl_client.py | 1 + .../LicenseAttachmentWorkflows_client.py | 3 +- .../LicenseRegistry/LicenseRegistry_client.py | 3 +- .../abi/LicenseToken/LicenseToken_client.py | 3 +- .../LicensingModule/LicensingModule_client.py | 3 +- .../abi/MockERC20/MockERC20_client.py | 3 +- .../ModuleRegistry/ModuleRegistry_client.py | 3 +- .../PILicenseTemplate_client.py | 3 +- .../RegistrationWorkflows_client.py | 3 +- .../abi/RoyaltyModule/RoyaltyModule_client.py | 3 +- .../RoyaltyPolicyLAP_client.py | 3 +- .../RoyaltyPolicyLRP_client.py | 3 +- ...oyaltyTokenDistributionWorkflows_client.py | 3 +- .../RoyaltyWorkflows_client.py | 3 +- .../abi/SPGNFTImpl/SPGNFTImpl_client.py | 1 + .../abi/WIP/WIP_client.py | 3 +- .../abi/jsons/AccessController.json | 2 +- .../abi/jsons/ArbitrationPolicyUMA.json | 2 +- .../abi/jsons/CoreMetadataModule.json | 2 +- .../abi/jsons/GroupingModule.json | 2 +- .../abi/jsons/GroupingWorkflows.json | 2 +- .../abi/jsons/LicensingModule.json | 2 +- .../abi/jsons/MockERC20.json | 2 +- .../abi/jsons/RoyaltyPolicyLAP.json | 2 +- .../abi/jsons/RoyaltyPolicyLRP.json | 2 +- .../abi/jsons/SPGNFTImpl.json | 2 +- .../abi/jsons/WIP.json | 2 +- .../resources/Dispute.py | 18 +++---- .../resources/Group.py | 21 ++++---- .../resources/IPAccount.py | 13 +++-- .../resources/IPAsset.py | 50 ++++++++----------- .../resources/License.py | 13 +++-- .../resources/NFTClient.py | 3 +- .../resources/Permission.py | 13 +++-- .../resources/Royalty.py | 19 ++++--- .../scripts/archive/generate_client.py | 9 ++-- .../archive/generate_client_from_abi.py | 3 +- .../scripts/archive/generate_client_impl.py | 9 ++-- .../archive/generate_client_impl_from_abi.py | 3 +- .../scripts/config.json | 8 +-- .../scripts/generate_clients.py | 5 +- src/story_protocol_python_sdk/story_client.py | 20 ++++---- src/story_protocol_python_sdk/utils/ipfs.py | 3 +- .../utils/license_terms.py | 2 +- src/story_protocol_python_sdk/utils/oov3.py | 2 + src/story_protocol_python_sdk/utils/sign.py | 15 +++--- tests/demo/demo.py | 20 ++++---- tests/integration/setup_for_integration.py | 46 ++++++++--------- tests/integration/test_integration_dispute.py | 16 +----- tests/integration/test_integration_group.py | 16 +++--- .../test_integration_ip_account.py | 20 ++++---- .../integration/test_integration_ip_asset.py | 21 ++++---- tests/integration/test_integration_license.py | 22 ++++---- .../test_integration_nft_client.py | 19 +++---- .../test_integration_permission.py | 9 ++-- tests/integration/test_integration_royalty.py | 22 ++++---- tests/integration/test_integration_wip.py | 4 +- tests/integration/utils.py | 10 ++-- tests/unit/fixtures/web3.py | 4 +- tests/unit/resources/test_ip_account.py | 10 ++-- tests/unit/resources/test_ip_asset.py | 8 +-- tests/unit/resources/test_license.py | 11 ++-- tests/unit/resources/test_permission.py | 5 +- tests/unit/resources/test_royalty.py | 17 ++++--- tests/unit/test_story_client.py | 10 ++-- 86 files changed, 315 insertions(+), 330 deletions(-) diff --git a/.coveragerc b/.coveragerc index cd12bbf..326685c 100644 --- a/.coveragerc +++ b/.coveragerc @@ -7,4 +7,3 @@ omit = # omit tests tests/* branch = true - diff --git a/.env-example b/.env-example index 4acc5d1..360b8bb 100644 --- a/.env-example +++ b/.env-example @@ -1,3 +1,3 @@ WALLET_PRIVATE_KEY=YOUR-PRIVATE-WALLET-KEY RPC_PROVIDER_URL=YOUR_RPC_URL -ETHERSCAN_API_KEY=YOUR-ETHERSCAN-API-KEY-HERE \ No newline at end of file +ETHERSCAN_API_KEY=YOUR-ETHERSCAN-API-KEY-HERE diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index e5b24e2..9a1d95f 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -6,10 +6,10 @@ This pr adds user login function, includes: - 1. add user login page. - 2. ... -## Test Plan - -Example: +Example: - 1. Use different test accounts for login tests, including correct user names and passwords, and incorrect user names and passwords. - 2. ... @@ -21,4 +21,4 @@ Example: Issue #123 ## Notes -- Example: Links and navigation need to be added to the front-end interface \ No newline at end of file +- Example: Links and navigation need to be added to the front-end interface diff --git a/.gitignore b/.gitignore index 2eb8c78..71ae301 100644 --- a/.gitignore +++ b/.gitignore @@ -111,4 +111,4 @@ virtualenv/ web3py.md # AI Assistant Configuration -CLAUDE.md \ No newline at end of file +CLAUDE.md diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8cabf22..09a86a6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -30,4 +30,4 @@ repos: rev: v0.8.4 hooks: - id: ruff - args: [--fix, --exit-non-zero-on-fix, --unsafe-fixes] \ No newline at end of file + args: [--fix, --exit-non-zero-on-fix, --unsafe-fixes] diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 50172ab..de49561 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -73,4 +73,4 @@ available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.ht [homepage]: https://www.contributor-covenant.org For answers to common questions about this code of conduct, see -https://www.contributor-covenant.org/faq \ No newline at end of file +https://www.contributor-covenant.org/faq diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 90a7039..722b6e2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -63,4 +63,4 @@ To make it easier for your PR to receive reviews, consider the reviewers will ne [1]: https://github.com/storyprotocol/typescript-sdk/issues [2]: https://chris.beams.io/posts/git-commit/#seven-rules -[3]: https://google.github.io/styleguide/tsguide.html \ No newline at end of file +[3]: https://google.github.io/styleguide/tsguide.html diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 69eafac..f61ce87 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -217,4 +217,4 @@ Before submitting a pull request: 3. Update tests if adding new functionality 4. Follow the existing code style and patterns -See [CONTRIBUTING.md](CONTRIBUTING.md) for more details. \ No newline at end of file +See [CONTRIBUTING.md](CONTRIBUTING.md) for more details. diff --git a/MANIFEST.in b/MANIFEST.in index c30c6a9..2ace150 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -3,4 +3,4 @@ include LICENSE include requirements.txt recursive-include src *.py *.json recursive-include src/story_protocol_python_sdk/abi *.json -recursive-include src/story_protocol_python_sdk/scripts *.json \ No newline at end of file +recursive-include src/story_protocol_python_sdk/scripts *.json diff --git a/pytest.ini b/pytest.ini index e701bf5..b7789cd 100644 --- a/pytest.ini +++ b/pytest.ini @@ -8,4 +8,4 @@ markers = addopts = -v -ra # ignore directories -norecursedirs = *.egg .git .* _darcs build dist venv \ No newline at end of file +norecursedirs = *.egg .git .* _darcs build dist venv diff --git a/src/story_protocol_python_sdk/__init__.py b/src/story_protocol_python_sdk/__init__.py index 4530bff..8520c85 100644 --- a/src/story_protocol_python_sdk/__init__.py +++ b/src/story_protocol_python_sdk/__init__.py @@ -1,13 +1,12 @@ __version__ = "0.3.14" -from .story_client import StoryClient +from .resources.Dispute import Dispute +from .resources.IPAccount import IPAccount from .resources.IPAsset import IPAsset from .resources.License import License from .resources.Royalty import Royalty -from .resources.IPAccount import IPAccount -from .resources.Dispute import Dispute from .resources.WIP import WIP - +from .story_client import StoryClient __all__ = [ "StoryClient", 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 d1956b2..0b6118f 100644 --- a/src/story_protocol_python_sdk/abi/AccessController/AccessController_client.py +++ b/src/story_protocol_python_sdk/abi/AccessController/AccessController_client.py @@ -1,5 +1,6 @@ import json import os + from web3 import Web3 @@ -21,7 +22,7 @@ def __init__(self, web3: Web3): break if not contract_address: raise ValueError( - f"Contract address for AccessController not found in config.json" + "Contract address for AccessController not found in config.json" ) abi_path = os.path.join( os.path.dirname(__file__), 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 b20b96a..cb61a57 100644 --- a/src/story_protocol_python_sdk/abi/ArbitrationPolicyUMA/ArbitrationPolicyUMA_client.py +++ b/src/story_protocol_python_sdk/abi/ArbitrationPolicyUMA/ArbitrationPolicyUMA_client.py @@ -1,5 +1,6 @@ import json import os + from web3 import Web3 @@ -21,7 +22,7 @@ def __init__(self, web3: Web3): break if not contract_address: raise ValueError( - f"Contract address for ArbitrationPolicyUMA not found in config.json" + "Contract address for ArbitrationPolicyUMA not found in config.json" ) abi_path = os.path.join( os.path.dirname(__file__), diff --git a/src/story_protocol_python_sdk/abi/CoreMetadataModule/CoreMetadataModule_client.py b/src/story_protocol_python_sdk/abi/CoreMetadataModule/CoreMetadataModule_client.py index 4e90177..2b38b62 100644 --- a/src/story_protocol_python_sdk/abi/CoreMetadataModule/CoreMetadataModule_client.py +++ b/src/story_protocol_python_sdk/abi/CoreMetadataModule/CoreMetadataModule_client.py @@ -1,5 +1,6 @@ import json import os + from web3 import Web3 @@ -21,7 +22,7 @@ def __init__(self, web3: Web3): break if not contract_address: raise ValueError( - f"Contract address for CoreMetadataModule not found in config.json" + "Contract address for CoreMetadataModule not found in config.json" ) abi_path = os.path.join( os.path.dirname(__file__), diff --git a/src/story_protocol_python_sdk/abi/CoreMetadataViewModule/CoreMetadataViewModule_client.py b/src/story_protocol_python_sdk/abi/CoreMetadataViewModule/CoreMetadataViewModule_client.py index 2ac514e..8c14566 100644 --- a/src/story_protocol_python_sdk/abi/CoreMetadataViewModule/CoreMetadataViewModule_client.py +++ b/src/story_protocol_python_sdk/abi/CoreMetadataViewModule/CoreMetadataViewModule_client.py @@ -1,5 +1,6 @@ import json import os + from web3 import Web3 @@ -22,7 +23,7 @@ def __init__(self, web3: Web3): break if not contract_address: raise ValueError( - f"Contract address for CoreMetadataViewModule not found in config.json" + "Contract address for CoreMetadataViewModule not found in config.json" ) abi_path = os.path.join( os.path.dirname(__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 bee3fb5..b1162b6 100644 --- a/src/story_protocol_python_sdk/abi/DerivativeWorkflows/DerivativeWorkflows_client.py +++ b/src/story_protocol_python_sdk/abi/DerivativeWorkflows/DerivativeWorkflows_client.py @@ -1,5 +1,6 @@ import json import os + from web3 import Web3 @@ -21,7 +22,7 @@ def __init__(self, web3: Web3): break if not contract_address: raise ValueError( - f"Contract address for DerivativeWorkflows not found in config.json" + "Contract address for DerivativeWorkflows not found in config.json" ) abi_path = os.path.join( os.path.dirname(__file__), 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 0dbb24f..2b8ae2f 100644 --- a/src/story_protocol_python_sdk/abi/DisputeModule/DisputeModule_client.py +++ b/src/story_protocol_python_sdk/abi/DisputeModule/DisputeModule_client.py @@ -1,5 +1,6 @@ import json import os + from web3 import Web3 @@ -21,7 +22,7 @@ def __init__(self, web3: Web3): break if not contract_address: raise ValueError( - f"Contract address for DisputeModule not found in config.json" + "Contract address for DisputeModule not found in config.json" ) abi_path = os.path.join( os.path.dirname(__file__), "..", "..", "abi", "jsons", "DisputeModule.json" diff --git a/src/story_protocol_python_sdk/abi/GroupingModule/GroupingModule_client.py b/src/story_protocol_python_sdk/abi/GroupingModule/GroupingModule_client.py index 0c988d6..ed8ffe1 100644 --- a/src/story_protocol_python_sdk/abi/GroupingModule/GroupingModule_client.py +++ b/src/story_protocol_python_sdk/abi/GroupingModule/GroupingModule_client.py @@ -1,5 +1,6 @@ import json import os + from web3 import Web3 @@ -21,7 +22,7 @@ def __init__(self, web3: Web3): break if not contract_address: raise ValueError( - f"Contract address for GroupingModule not found in config.json" + "Contract address for GroupingModule not found in config.json" ) abi_path = os.path.join( os.path.dirname(__file__), "..", "..", "abi", "jsons", "GroupingModule.json" 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 1c1b0bb..24dcf45 100644 --- a/src/story_protocol_python_sdk/abi/GroupingWorkflows/GroupingWorkflows_client.py +++ b/src/story_protocol_python_sdk/abi/GroupingWorkflows/GroupingWorkflows_client.py @@ -1,5 +1,6 @@ import json import os + from web3 import Web3 @@ -21,7 +22,7 @@ def __init__(self, web3: Web3): break if not contract_address: raise ValueError( - f"Contract address for GroupingWorkflows not found in config.json" + "Contract address for GroupingWorkflows not found in config.json" ) abi_path = os.path.join( os.path.dirname(__file__), 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 d676f41..de9809b 100644 --- a/src/story_protocol_python_sdk/abi/IPAccountImpl/IPAccountImpl_client.py +++ b/src/story_protocol_python_sdk/abi/IPAccountImpl/IPAccountImpl_client.py @@ -1,5 +1,6 @@ import json import os + from web3 import Web3 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 eb1a457..9d753c6 100644 --- a/src/story_protocol_python_sdk/abi/IPAssetRegistry/IPAssetRegistry_client.py +++ b/src/story_protocol_python_sdk/abi/IPAssetRegistry/IPAssetRegistry_client.py @@ -1,5 +1,6 @@ import json import os + from web3 import Web3 @@ -21,7 +22,7 @@ def __init__(self, web3: Web3): break if not contract_address: raise ValueError( - f"Contract address for IPAssetRegistry not found in config.json" + "Contract address for IPAssetRegistry not found in config.json" ) abi_path = os.path.join( os.path.dirname(__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 4fff409..2fb66d3 100644 --- a/src/story_protocol_python_sdk/abi/IpRoyaltyVaultImpl/IpRoyaltyVaultImpl_client.py +++ b/src/story_protocol_python_sdk/abi/IpRoyaltyVaultImpl/IpRoyaltyVaultImpl_client.py @@ -1,5 +1,6 @@ import json import os + from web3 import Web3 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 3bbe154..92d509a 100644 --- a/src/story_protocol_python_sdk/abi/LicenseAttachmentWorkflows/LicenseAttachmentWorkflows_client.py +++ b/src/story_protocol_python_sdk/abi/LicenseAttachmentWorkflows/LicenseAttachmentWorkflows_client.py @@ -1,5 +1,6 @@ import json import os + from web3 import Web3 @@ -21,7 +22,7 @@ def __init__(self, web3: Web3): break if not contract_address: raise ValueError( - f"Contract address for LicenseAttachmentWorkflows not found in config.json" + "Contract address for LicenseAttachmentWorkflows not found in config.json" ) abi_path = os.path.join( os.path.dirname(__file__), 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 824a47e..12e9eb7 100644 --- a/src/story_protocol_python_sdk/abi/LicenseRegistry/LicenseRegistry_client.py +++ b/src/story_protocol_python_sdk/abi/LicenseRegistry/LicenseRegistry_client.py @@ -1,5 +1,6 @@ import json import os + from web3 import Web3 @@ -21,7 +22,7 @@ def __init__(self, web3: Web3): break if not contract_address: raise ValueError( - f"Contract address for LicenseRegistry not found in config.json" + "Contract address for LicenseRegistry not found in config.json" ) abi_path = os.path.join( os.path.dirname(__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 1720e0a..aa542e6 100644 --- a/src/story_protocol_python_sdk/abi/LicenseToken/LicenseToken_client.py +++ b/src/story_protocol_python_sdk/abi/LicenseToken/LicenseToken_client.py @@ -1,5 +1,6 @@ import json import os + from web3 import Web3 @@ -21,7 +22,7 @@ def __init__(self, web3: Web3): break if not contract_address: raise ValueError( - f"Contract address for LicenseToken not found in config.json" + "Contract address for LicenseToken not found in config.json" ) abi_path = os.path.join( os.path.dirname(__file__), "..", "..", "abi", "jsons", "LicenseToken.json" 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 cf01b15..cfeb624 100644 --- a/src/story_protocol_python_sdk/abi/LicensingModule/LicensingModule_client.py +++ b/src/story_protocol_python_sdk/abi/LicensingModule/LicensingModule_client.py @@ -1,5 +1,6 @@ import json import os + from web3 import Web3 @@ -21,7 +22,7 @@ def __init__(self, web3: Web3): break if not contract_address: raise ValueError( - f"Contract address for LicensingModule not found in config.json" + "Contract address for LicensingModule not found in config.json" ) abi_path = os.path.join( os.path.dirname(__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 a51a7d4..14c11bd 100644 --- a/src/story_protocol_python_sdk/abi/MockERC20/MockERC20_client.py +++ b/src/story_protocol_python_sdk/abi/MockERC20/MockERC20_client.py @@ -1,5 +1,6 @@ import json import os + from web3 import Web3 @@ -20,7 +21,7 @@ def __init__(self, web3: Web3): contract_address = contract["contract_address"] break if not contract_address: - raise ValueError(f"Contract address for MockERC20 not found in config.json") + raise ValueError("Contract address for MockERC20 not found in config.json") abi_path = os.path.join( os.path.dirname(__file__), "..", "..", "abi", "jsons", "MockERC20.json" ) 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 bfcc1b6..757dde0 100644 --- a/src/story_protocol_python_sdk/abi/ModuleRegistry/ModuleRegistry_client.py +++ b/src/story_protocol_python_sdk/abi/ModuleRegistry/ModuleRegistry_client.py @@ -1,5 +1,6 @@ import json import os + from web3 import Web3 @@ -21,7 +22,7 @@ def __init__(self, web3: Web3): break if not contract_address: raise ValueError( - f"Contract address for ModuleRegistry not found in config.json" + "Contract address for ModuleRegistry not found in config.json" ) abi_path = os.path.join( os.path.dirname(__file__), "..", "..", "abi", "jsons", "ModuleRegistry.json" 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 9b5b8e8..d83a232 100644 --- a/src/story_protocol_python_sdk/abi/PILicenseTemplate/PILicenseTemplate_client.py +++ b/src/story_protocol_python_sdk/abi/PILicenseTemplate/PILicenseTemplate_client.py @@ -1,5 +1,6 @@ import json import os + from web3 import Web3 @@ -21,7 +22,7 @@ def __init__(self, web3: Web3): break if not contract_address: raise ValueError( - f"Contract address for PILicenseTemplate not found in config.json" + "Contract address for PILicenseTemplate not found in config.json" ) abi_path = os.path.join( os.path.dirname(__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 76c0298..25323f0 100644 --- a/src/story_protocol_python_sdk/abi/RegistrationWorkflows/RegistrationWorkflows_client.py +++ b/src/story_protocol_python_sdk/abi/RegistrationWorkflows/RegistrationWorkflows_client.py @@ -1,5 +1,6 @@ import json import os + from web3 import Web3 @@ -21,7 +22,7 @@ def __init__(self, web3: Web3): break if not contract_address: raise ValueError( - f"Contract address for RegistrationWorkflows not found in config.json" + "Contract address for RegistrationWorkflows not found in config.json" ) abi_path = os.path.join( os.path.dirname(__file__), 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 1907130..bf15287 100644 --- a/src/story_protocol_python_sdk/abi/RoyaltyModule/RoyaltyModule_client.py +++ b/src/story_protocol_python_sdk/abi/RoyaltyModule/RoyaltyModule_client.py @@ -1,5 +1,6 @@ import json import os + from web3 import Web3 @@ -21,7 +22,7 @@ def __init__(self, web3: Web3): break if not contract_address: raise ValueError( - f"Contract address for RoyaltyModule not found in config.json" + "Contract address for RoyaltyModule not found in config.json" ) abi_path = os.path.join( os.path.dirname(__file__), "..", "..", "abi", "jsons", "RoyaltyModule.json" diff --git a/src/story_protocol_python_sdk/abi/RoyaltyPolicyLAP/RoyaltyPolicyLAP_client.py b/src/story_protocol_python_sdk/abi/RoyaltyPolicyLAP/RoyaltyPolicyLAP_client.py index f553857..e01bfd3 100644 --- a/src/story_protocol_python_sdk/abi/RoyaltyPolicyLAP/RoyaltyPolicyLAP_client.py +++ b/src/story_protocol_python_sdk/abi/RoyaltyPolicyLAP/RoyaltyPolicyLAP_client.py @@ -1,5 +1,6 @@ import json import os + from web3 import Web3 @@ -21,7 +22,7 @@ def __init__(self, web3: Web3): break if not contract_address: raise ValueError( - f"Contract address for RoyaltyPolicyLAP not found in config.json" + "Contract address for RoyaltyPolicyLAP not found in config.json" ) abi_path = os.path.join( os.path.dirname(__file__), diff --git a/src/story_protocol_python_sdk/abi/RoyaltyPolicyLRP/RoyaltyPolicyLRP_client.py b/src/story_protocol_python_sdk/abi/RoyaltyPolicyLRP/RoyaltyPolicyLRP_client.py index 62ad2f7..8fb93a2 100644 --- a/src/story_protocol_python_sdk/abi/RoyaltyPolicyLRP/RoyaltyPolicyLRP_client.py +++ b/src/story_protocol_python_sdk/abi/RoyaltyPolicyLRP/RoyaltyPolicyLRP_client.py @@ -1,5 +1,6 @@ import json import os + from web3 import Web3 @@ -21,7 +22,7 @@ def __init__(self, web3: Web3): break if not contract_address: raise ValueError( - f"Contract address for RoyaltyPolicyLRP not found in config.json" + "Contract address for RoyaltyPolicyLRP not found in config.json" ) abi_path = os.path.join( os.path.dirname(__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 407cb80..651e3bb 100644 --- a/src/story_protocol_python_sdk/abi/RoyaltyTokenDistributionWorkflows/RoyaltyTokenDistributionWorkflows_client.py +++ b/src/story_protocol_python_sdk/abi/RoyaltyTokenDistributionWorkflows/RoyaltyTokenDistributionWorkflows_client.py @@ -1,5 +1,6 @@ import json import os + from web3 import Web3 @@ -21,7 +22,7 @@ def __init__(self, web3: Web3): break if not contract_address: raise ValueError( - f"Contract address for RoyaltyTokenDistributionWorkflows not found in config.json" + "Contract address for RoyaltyTokenDistributionWorkflows not found in config.json" ) abi_path = os.path.join( os.path.dirname(__file__), 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 91884c3..1a8270b 100644 --- a/src/story_protocol_python_sdk/abi/RoyaltyWorkflows/RoyaltyWorkflows_client.py +++ b/src/story_protocol_python_sdk/abi/RoyaltyWorkflows/RoyaltyWorkflows_client.py @@ -1,5 +1,6 @@ import json import os + from web3 import Web3 @@ -21,7 +22,7 @@ def __init__(self, web3: Web3): break if not contract_address: raise ValueError( - f"Contract address for RoyaltyWorkflows not found in config.json" + "Contract address for RoyaltyWorkflows not found in config.json" ) abi_path = os.path.join( os.path.dirname(__file__), 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 f19a684..4490654 100644 --- a/src/story_protocol_python_sdk/abi/SPGNFTImpl/SPGNFTImpl_client.py +++ b/src/story_protocol_python_sdk/abi/SPGNFTImpl/SPGNFTImpl_client.py @@ -1,5 +1,6 @@ import json import os + from web3 import Web3 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 0587c65..d3229c9 100644 --- a/src/story_protocol_python_sdk/abi/WIP/WIP_client.py +++ b/src/story_protocol_python_sdk/abi/WIP/WIP_client.py @@ -1,5 +1,6 @@ import json import os + from web3 import Web3 @@ -20,7 +21,7 @@ def __init__(self, web3: Web3): contract_address = contract["contract_address"] break if not contract_address: - raise ValueError(f"Contract address for WIP not found in config.json") + raise ValueError("Contract address for WIP not found in config.json") abi_path = os.path.join( os.path.dirname(__file__), "..", "..", "abi", "jsons", "WIP.json" ) diff --git a/src/story_protocol_python_sdk/abi/jsons/AccessController.json b/src/story_protocol_python_sdk/abi/jsons/AccessController.json index 72ebaac..85f0230 100644 --- a/src/story_protocol_python_sdk/abi/jsons/AccessController.json +++ b/src/story_protocol_python_sdk/abi/jsons/AccessController.json @@ -865,4 +865,4 @@ "stateMutability": "payable", "type": "function" } -] \ No newline at end of file +] diff --git a/src/story_protocol_python_sdk/abi/jsons/ArbitrationPolicyUMA.json b/src/story_protocol_python_sdk/abi/jsons/ArbitrationPolicyUMA.json index 08c0da1..a665035 100644 --- a/src/story_protocol_python_sdk/abi/jsons/ArbitrationPolicyUMA.json +++ b/src/story_protocol_python_sdk/abi/jsons/ArbitrationPolicyUMA.json @@ -936,4 +936,4 @@ "stateMutability": "payable", "type": "function" } - ] \ No newline at end of file + ] diff --git a/src/story_protocol_python_sdk/abi/jsons/CoreMetadataModule.json b/src/story_protocol_python_sdk/abi/jsons/CoreMetadataModule.json index 2f71ec6..ba76b87 100644 --- a/src/story_protocol_python_sdk/abi/jsons/CoreMetadataModule.json +++ b/src/story_protocol_python_sdk/abi/jsons/CoreMetadataModule.json @@ -494,4 +494,4 @@ "stateMutability": "payable", "type": "function" } -] \ No newline at end of file +] diff --git a/src/story_protocol_python_sdk/abi/jsons/GroupingModule.json b/src/story_protocol_python_sdk/abi/jsons/GroupingModule.json index 3de9243..b80ab61 100644 --- a/src/story_protocol_python_sdk/abi/jsons/GroupingModule.json +++ b/src/story_protocol_python_sdk/abi/jsons/GroupingModule.json @@ -1048,4 +1048,4 @@ "stateMutability": "nonpayable", "type": "function" } -] \ No newline at end of file +] diff --git a/src/story_protocol_python_sdk/abi/jsons/GroupingWorkflows.json b/src/story_protocol_python_sdk/abi/jsons/GroupingWorkflows.json index 18d56b7..24f0158 100644 --- a/src/story_protocol_python_sdk/abi/jsons/GroupingWorkflows.json +++ b/src/story_protocol_python_sdk/abi/jsons/GroupingWorkflows.json @@ -1313,4 +1313,4 @@ "stateMutability": "payable", "type": "function" } -] \ No newline at end of file +] diff --git a/src/story_protocol_python_sdk/abi/jsons/LicensingModule.json b/src/story_protocol_python_sdk/abi/jsons/LicensingModule.json index 2742686..d0078fe 100644 --- a/src/story_protocol_python_sdk/abi/jsons/LicensingModule.json +++ b/src/story_protocol_python_sdk/abi/jsons/LicensingModule.json @@ -1354,4 +1354,4 @@ "stateMutability": "payable", "type": "function" } -] \ No newline at end of file +] diff --git a/src/story_protocol_python_sdk/abi/jsons/MockERC20.json b/src/story_protocol_python_sdk/abi/jsons/MockERC20.json index db82bcf..e466ba0 100644 --- a/src/story_protocol_python_sdk/abi/jsons/MockERC20.json +++ b/src/story_protocol_python_sdk/abi/jsons/MockERC20.json @@ -348,4 +348,4 @@ "stateMutability": "nonpayable", "type": "function" } - ] \ No newline at end of file + ] diff --git a/src/story_protocol_python_sdk/abi/jsons/RoyaltyPolicyLAP.json b/src/story_protocol_python_sdk/abi/jsons/RoyaltyPolicyLAP.json index 8ff970d..bfd28b0 100644 --- a/src/story_protocol_python_sdk/abi/jsons/RoyaltyPolicyLAP.json +++ b/src/story_protocol_python_sdk/abi/jsons/RoyaltyPolicyLAP.json @@ -648,4 +648,4 @@ "stateMutability": "payable", "type": "function" } -] \ No newline at end of file +] diff --git a/src/story_protocol_python_sdk/abi/jsons/RoyaltyPolicyLRP.json b/src/story_protocol_python_sdk/abi/jsons/RoyaltyPolicyLRP.json index 30795e4..77719f5 100644 --- a/src/story_protocol_python_sdk/abi/jsons/RoyaltyPolicyLRP.json +++ b/src/story_protocol_python_sdk/abi/jsons/RoyaltyPolicyLRP.json @@ -671,4 +671,4 @@ "stateMutability": "payable", "type": "function" } -] \ No newline at end of file +] diff --git a/src/story_protocol_python_sdk/abi/jsons/SPGNFTImpl.json b/src/story_protocol_python_sdk/abi/jsons/SPGNFTImpl.json index 74820d5..a8aa782 100644 --- a/src/story_protocol_python_sdk/abi/jsons/SPGNFTImpl.json +++ b/src/story_protocol_python_sdk/abi/jsons/SPGNFTImpl.json @@ -1232,4 +1232,4 @@ "stateMutability": "nonpayable", "type": "function" } - ] \ No newline at end of file + ] diff --git a/src/story_protocol_python_sdk/abi/jsons/WIP.json b/src/story_protocol_python_sdk/abi/jsons/WIP.json index 4d2b58a..b20ca3f 100644 --- a/src/story_protocol_python_sdk/abi/jsons/WIP.json +++ b/src/story_protocol_python_sdk/abi/jsons/WIP.json @@ -425,4 +425,4 @@ "stateMutability": "payable", "type": "receive" } - ] \ 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 e9fd344..0fc7355 100644 --- a/src/story_protocol_python_sdk/resources/Dispute.py +++ b/src/story_protocol_python_sdk/resources/Dispute.py @@ -1,22 +1,20 @@ -from web3 import Web3 from eth_abi.abi import encode +from web3 import Web3 -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.abi.DisputeModule.DisputeModule_client import ( + DisputeModuleClient, +) from story_protocol_python_sdk.abi.IPAccountImpl.IPAccountImpl_client import ( IPAccountImplClient, ) from story_protocol_python_sdk.abi.WIP.WIP_client import WIPClient - -from story_protocol_python_sdk.utils.transaction_utils import build_and_send_transaction +from story_protocol_python_sdk.resources.WIP import WIP from story_protocol_python_sdk.utils.ipfs import convert_cid_to_hash_ipfs -from story_protocol_python_sdk.utils.constants import ZERO_ADDRESS from story_protocol_python_sdk.utils.oov3 import get_assertion_bond +from story_protocol_python_sdk.utils.transaction_utils import build_and_send_transaction class Dispute: @@ -101,7 +99,7 @@ def raise_dispute( if bond > max_bonds: raise ValueError(f"Bond must be less than {max_bonds}.") - deposit_response = self.wip.deposit(amount=bond) + self.wip.deposit(amount=bond) # Convert CID to IPFS hash dispute_evidence_hash = convert_cid_to_hash_ipfs(cid) @@ -297,7 +295,7 @@ def dispute_assertion( # Approve IP Account to transfer WrappedIP tokens if needed if allowance < bond: - approve_tx = self.wip.approve( + self.wip.approve( spender=ip_account.contract.address, amount=2**256 - 1 # maxUint256 ) diff --git a/src/story_protocol_python_sdk/resources/Group.py b/src/story_protocol_python_sdk/resources/Group.py index 079c7ad..dba882e 100644 --- a/src/story_protocol_python_sdk/resources/Group.py +++ b/src/story_protocol_python_sdk/resources/Group.py @@ -2,35 +2,34 @@ from web3 import Web3 +from story_protocol_python_sdk.abi.CoreMetadataModule.CoreMetadataModule_client import ( + CoreMetadataModuleClient, +) from story_protocol_python_sdk.abi.GroupingModule.GroupingModule_client import ( GroupingModuleClient, ) from story_protocol_python_sdk.abi.GroupingWorkflows.GroupingWorkflows_client import ( GroupingWorkflowsClient, ) +from story_protocol_python_sdk.abi.IPAccountImpl.IPAccountImpl_client import ( + IPAccountImplClient, +) from story_protocol_python_sdk.abi.IPAssetRegistry.IPAssetRegistry_client import ( IPAssetRegistryClient, ) -from story_protocol_python_sdk.abi.CoreMetadataModule.CoreMetadataModule_client import ( - CoreMetadataModuleClient, +from story_protocol_python_sdk.abi.LicenseRegistry.LicenseRegistry_client import ( + LicenseRegistryClient, ) from story_protocol_python_sdk.abi.LicensingModule.LicensingModule_client import ( LicensingModuleClient, ) -from story_protocol_python_sdk.abi.LicenseRegistry.LicenseRegistry_client import ( - LicenseRegistryClient, -) from story_protocol_python_sdk.abi.PILicenseTemplate.PILicenseTemplate_client import ( PILicenseTemplateClient, ) -from story_protocol_python_sdk.abi.IPAccountImpl.IPAccountImpl_client import ( - IPAccountImplClient, -) - +from story_protocol_python_sdk.utils.constants import ZERO_ADDRESS, ZERO_HASH 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 -from story_protocol_python_sdk.utils.constants import ZERO_ADDRESS, ZERO_HASH +from story_protocol_python_sdk.utils.transaction_utils import build_and_send_transaction class Group: diff --git a/src/story_protocol_python_sdk/resources/IPAccount.py b/src/story_protocol_python_sdk/resources/IPAccount.py index 32fada8..facab3c 100644 --- a/src/story_protocol_python_sdk/resources/IPAccount.py +++ b/src/story_protocol_python_sdk/resources/IPAccount.py @@ -2,20 +2,19 @@ from web3 import Web3 -from story_protocol_python_sdk.abi.IPAccountImpl.IPAccountImpl_client import ( - IPAccountImplClient, -) -from story_protocol_python_sdk.abi.IPAssetRegistry.IPAssetRegistry_client import ( - IPAssetRegistryClient, -) from story_protocol_python_sdk.abi.AccessController.AccessController_client import ( AccessControllerClient, ) from story_protocol_python_sdk.abi.CoreMetadataModule.CoreMetadataModule_client import ( CoreMetadataModuleClient, ) +from story_protocol_python_sdk.abi.IPAccountImpl.IPAccountImpl_client import ( + IPAccountImplClient, +) +from story_protocol_python_sdk.abi.IPAssetRegistry.IPAssetRegistry_client import ( + IPAssetRegistryClient, +) from story_protocol_python_sdk.abi.MockERC20.MockERC20_client import MockERC20Client - from story_protocol_python_sdk.utils.transaction_utils import build_and_send_transaction diff --git a/src/story_protocol_python_sdk/resources/IPAsset.py b/src/story_protocol_python_sdk/resources/IPAsset.py index 0278649..11eb3ca 100644 --- a/src/story_protocol_python_sdk/resources/IPAsset.py +++ b/src/story_protocol_python_sdk/resources/IPAsset.py @@ -2,43 +2,41 @@ from web3 import Web3 -from story_protocol_python_sdk.abi.IPAssetRegistry.IPAssetRegistry_client import ( - IPAssetRegistryClient, -) -from story_protocol_python_sdk.abi.LicensingModule.LicensingModule_client import ( - LicensingModuleClient, +from story_protocol_python_sdk.abi.AccessController.AccessController_client import ( + AccessControllerClient, ) -from story_protocol_python_sdk.abi.LicenseToken.LicenseToken_client import ( - LicenseTokenClient, +from story_protocol_python_sdk.abi.CoreMetadataModule.CoreMetadataModule_client import ( + CoreMetadataModuleClient, ) -from story_protocol_python_sdk.abi.LicenseRegistry.LicenseRegistry_client import ( - LicenseRegistryClient, +from story_protocol_python_sdk.abi.DerivativeWorkflows.DerivativeWorkflows_client import ( + DerivativeWorkflowsClient, ) -from story_protocol_python_sdk.abi.RegistrationWorkflows.RegistrationWorkflows_client import ( - RegistrationWorkflowsClient, +from story_protocol_python_sdk.abi.IPAssetRegistry.IPAssetRegistry_client import ( + IPAssetRegistryClient, ) from story_protocol_python_sdk.abi.LicenseAttachmentWorkflows.LicenseAttachmentWorkflows_client import ( LicenseAttachmentWorkflowsClient, ) -from story_protocol_python_sdk.abi.DerivativeWorkflows.DerivativeWorkflows_client import ( - DerivativeWorkflowsClient, +from story_protocol_python_sdk.abi.LicenseRegistry.LicenseRegistry_client import ( + LicenseRegistryClient, ) -from story_protocol_python_sdk.abi.CoreMetadataModule.CoreMetadataModule_client import ( - CoreMetadataModuleClient, +from story_protocol_python_sdk.abi.LicenseToken.LicenseToken_client import ( + LicenseTokenClient, ) -from story_protocol_python_sdk.abi.AccessController.AccessController_client import ( - AccessControllerClient, +from story_protocol_python_sdk.abi.LicensingModule.LicensingModule_client import ( + LicensingModuleClient, ) from story_protocol_python_sdk.abi.PILicenseTemplate.PILicenseTemplate_client import ( PILicenseTemplateClient, ) - +from story_protocol_python_sdk.abi.RegistrationWorkflows.RegistrationWorkflows_client import ( + RegistrationWorkflowsClient, +) +from story_protocol_python_sdk.abi.SPGNFTImpl.SPGNFTImpl_client import SPGNFTImplClient +from story_protocol_python_sdk.utils.constants import ZERO_ADDRESS, ZERO_HASH 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 -from story_protocol_python_sdk.utils.constants import ZERO_ADDRESS, ZERO_HASH - -from story_protocol_python_sdk.abi.SPGNFTImpl.SPGNFTImpl_client import SPGNFTImplClient +from story_protocol_python_sdk.utils.transaction_utils import build_and_send_transaction class IPAsset: @@ -403,9 +401,7 @@ def mint_and_register_ip_asset_with_pil_terms( license_terms = [] for term in terms: - validated_term = self.license_terms_util.validate_license_terms( - term["terms"] - ) + self.license_terms_util.validate_license_terms(term["terms"]) validated_licensing_config = ( self.license_terms_util.validate_licensing_config( term["licensing_config"] @@ -632,9 +628,7 @@ def register_ip_and_attach_pil_terms( license_terms = [] for term in license_terms_data: - validated_term = self.license_terms_util.validate_license_terms( - term["terms"] - ) + self.license_terms_util.validate_license_terms(term["terms"]) validated_licensing_config = ( self.license_terms_util.validate_licensing_config( term["licensing_config"] diff --git a/src/story_protocol_python_sdk/resources/License.py b/src/story_protocol_python_sdk/resources/License.py index 65869b9..2381680 100644 --- a/src/story_protocol_python_sdk/resources/License.py +++ b/src/story_protocol_python_sdk/resources/License.py @@ -2,8 +2,8 @@ from web3 import Web3 -from story_protocol_python_sdk.abi.PILicenseTemplate.PILicenseTemplate_client import ( - PILicenseTemplateClient, +from story_protocol_python_sdk.abi.IPAssetRegistry.IPAssetRegistry_client import ( + IPAssetRegistryClient, ) from story_protocol_python_sdk.abi.LicenseRegistry.LicenseRegistry_client import ( LicenseRegistryClient, @@ -11,16 +11,15 @@ 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.abi.PILicenseTemplate.PILicenseTemplate_client import ( + PILicenseTemplateClient, +) +from story_protocol_python_sdk.utils.constants import ZERO_ADDRESS 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.constants import ZERO_ADDRESS class License: diff --git a/src/story_protocol_python_sdk/resources/NFTClient.py b/src/story_protocol_python_sdk/resources/NFTClient.py index 05d064d..41a7217 100644 --- a/src/story_protocol_python_sdk/resources/NFTClient.py +++ b/src/story_protocol_python_sdk/resources/NFTClient.py @@ -6,9 +6,8 @@ RegistrationWorkflowsClient, ) from story_protocol_python_sdk.abi.SPGNFTImpl.SPGNFTImpl_client import SPGNFTImplClient - +from story_protocol_python_sdk.utils.constants import ZERO_ADDRESS from story_protocol_python_sdk.utils.transaction_utils import build_and_send_transaction -from story_protocol_python_sdk.utils.constants import ZERO_ADDRESS, ZERO_HASH class NFTClient: diff --git a/src/story_protocol_python_sdk/resources/Permission.py b/src/story_protocol_python_sdk/resources/Permission.py index bec23be..3bcc992 100644 --- a/src/story_protocol_python_sdk/resources/Permission.py +++ b/src/story_protocol_python_sdk/resources/Permission.py @@ -1,22 +1,21 @@ # src/story_protcol_python_sdk/resources/Permission.py + from web3 import Web3 -import os, json +from story_protocol_python_sdk.abi.AccessController.AccessController_client import ( + AccessControllerClient, +) from story_protocol_python_sdk.abi.IPAccountImpl.IPAccountImpl_client import ( IPAccountImplClient, ) from story_protocol_python_sdk.abi.IPAssetRegistry.IPAssetRegistry_client import ( IPAssetRegistryClient, ) -from story_protocol_python_sdk.abi.AccessController.AccessController_client import ( - AccessControllerClient, -) from story_protocol_python_sdk.resources.IPAccount import IPAccount -from story_protocol_python_sdk.utils.transaction_utils import build_and_send_transaction -from story_protocol_python_sdk.utils.validation import validate_address from story_protocol_python_sdk.utils.constants import DEFAULT_FUNCTION_SELECTOR from story_protocol_python_sdk.utils.sign import Sign +from story_protocol_python_sdk.utils.validation import validate_address class Permission: @@ -181,7 +180,7 @@ def create_set_permission_signature( # Get state and calculate deadline state = ip_account_client.state() - block_timestamp = self.web3.eth.get_block("latest").timestamp + self.web3.eth.get_block("latest").timestamp calculated_deadline = self.sign_util.get_deadline(deadline) # Get permission signature diff --git a/src/story_protocol_python_sdk/resources/Royalty.py b/src/story_protocol_python_sdk/resources/Royalty.py index a09f302..100965f 100644 --- a/src/story_protocol_python_sdk/resources/Royalty.py +++ b/src/story_protocol_python_sdk/resources/Royalty.py @@ -2,29 +2,28 @@ from web3 import Web3 +from story_protocol_python_sdk.abi.IPAccountImpl.IPAccountImpl_client import ( + IPAccountImplClient, +) from story_protocol_python_sdk.abi.IPAssetRegistry.IPAssetRegistry_client import ( IPAssetRegistryClient, ) from story_protocol_python_sdk.abi.IpRoyaltyVaultImpl.IpRoyaltyVaultImpl_client import ( IpRoyaltyVaultImplClient, ) -from story_protocol_python_sdk.abi.RoyaltyPolicyLAP.RoyaltyPolicyLAP_client import ( - RoyaltyPolicyLAPClient, -) +from story_protocol_python_sdk.abi.MockERC20.MockERC20_client import MockERC20Client from story_protocol_python_sdk.abi.RoyaltyModule.RoyaltyModule_client import ( RoyaltyModuleClient, ) -from story_protocol_python_sdk.abi.RoyaltyWorkflows.RoyaltyWorkflows_client import ( - RoyaltyWorkflowsClient, -) -from story_protocol_python_sdk.abi.IPAccountImpl.IPAccountImpl_client import ( - IPAccountImplClient, +from story_protocol_python_sdk.abi.RoyaltyPolicyLAP.RoyaltyPolicyLAP_client import ( + RoyaltyPolicyLAPClient, ) -from story_protocol_python_sdk.abi.MockERC20.MockERC20_client import MockERC20Client from story_protocol_python_sdk.abi.RoyaltyPolicyLRP.RoyaltyPolicyLRP_client import ( RoyaltyPolicyLRPClient, ) - +from story_protocol_python_sdk.abi.RoyaltyWorkflows.RoyaltyWorkflows_client import ( + RoyaltyWorkflowsClient, +) from story_protocol_python_sdk.utils.transaction_utils import build_and_send_transaction diff --git a/src/story_protocol_python_sdk/scripts/archive/generate_client.py b/src/story_protocol_python_sdk/scripts/archive/generate_client.py index ccc4b84..b4edcfa 100644 --- a/src/story_protocol_python_sdk/scripts/archive/generate_client.py +++ b/src/story_protocol_python_sdk/scripts/archive/generate_client.py @@ -1,12 +1,13 @@ # scripts/generate_client.py -import requests import json import os -from jinja2 import Template -from dotenv import load_dotenv import time +import requests +from dotenv import load_dotenv +from jinja2 import Template + # Load environment variables from .env file load_dotenv(os.path.join(os.path.dirname(__file__), "..", "..", "..", ".env")) @@ -103,7 +104,7 @@ def {{ function.name }}(self, {% if function.inputs %}{{ function.inputs | join( 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): return self.contract.functions.{{ function.name }}({% if function.inputs %}{{ function.inputs | join(', ') }}{% endif %}).build_transaction(tx_params) {% endif %} diff --git a/src/story_protocol_python_sdk/scripts/archive/generate_client_from_abi.py b/src/story_protocol_python_sdk/scripts/archive/generate_client_from_abi.py index 8985670..989bf93 100644 --- a/src/story_protocol_python_sdk/scripts/archive/generate_client_from_abi.py +++ b/src/story_protocol_python_sdk/scripts/archive/generate_client_from_abi.py @@ -1,5 +1,6 @@ import json import os + from jinja2 import Template # Load ABIs from the correct jsons folder @@ -35,7 +36,7 @@ def {{ function.name }}(self, {% if function.inputs %}{{ function.inputs | join( 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): return self.contract.functions.{{ function.name }}({% if function.inputs %}{{ function.inputs | join(', ') }}{% endif %}).build_transaction(tx_params) {% endif %} diff --git a/src/story_protocol_python_sdk/scripts/archive/generate_client_impl.py b/src/story_protocol_python_sdk/scripts/archive/generate_client_impl.py index eb13de0..4da3d07 100644 --- a/src/story_protocol_python_sdk/scripts/archive/generate_client_impl.py +++ b/src/story_protocol_python_sdk/scripts/archive/generate_client_impl.py @@ -1,10 +1,11 @@ -import requests import json import os -from jinja2 import Template -from dotenv import load_dotenv import time +import requests +from dotenv import load_dotenv +from jinja2 import Template + # Load environment variables from .env file load_dotenv(os.path.join(os.path.dirname(__file__), "..", "..", "..", ".env")) @@ -51,7 +52,7 @@ def {{ function.name }}(self, {% if function.inputs %}{{ function.inputs | join( 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): return self.contract.functions.{{ function.name }}({% if function.inputs %}{{ function.inputs | join(', ') }}{% endif %}).build_transaction(tx_params) {% endif %} diff --git a/src/story_protocol_python_sdk/scripts/archive/generate_client_impl_from_abi.py b/src/story_protocol_python_sdk/scripts/archive/generate_client_impl_from_abi.py index 501bcb4..bd7575e 100644 --- a/src/story_protocol_python_sdk/scripts/archive/generate_client_impl_from_abi.py +++ b/src/story_protocol_python_sdk/scripts/archive/generate_client_impl_from_abi.py @@ -1,5 +1,6 @@ import json import os + from jinja2 import Template # Define the folder containing the ABI JSON files @@ -24,7 +25,7 @@ def {{ function.name }}(self, {% if function.inputs %}{{ function.inputs | join( 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): return self.contract.functions.{{ function.name }}({% if function.inputs %}{{ function.inputs | join(', ') }}{% endif %}).build_transaction(tx_params) {% endif %} diff --git a/src/story_protocol_python_sdk/scripts/config.json b/src/story_protocol_python_sdk/scripts/config.json index df8ee59..ed90911 100644 --- a/src/story_protocol_python_sdk/scripts/config.json +++ b/src/story_protocol_python_sdk/scripts/config.json @@ -5,7 +5,7 @@ "contract_address": "0xcCF37d0a503Ee1D4C11208672e622ed3DFB2275a", "functions": [ "PermissionSet", - "setPermission", + "setPermission", "setAllPermissions", "setBatchPermissions", "setTransientPermission", @@ -17,7 +17,7 @@ "contract_address": "0x9b7A9c70AFF961C799110954fc06F3093aeb94C5", "functions": [ "DisputeCancelled", - "DisputeRaised", + "DisputeRaised", "DisputeResolved", "cancelDispute", "raiseDispute", @@ -43,7 +43,7 @@ "functions": [ "IPRegistered", "ipId", - "isRegistered", + "isRegistered", "register", "IPAccountRegistered" ] @@ -210,7 +210,7 @@ "functions": ["transferToVault"] }, { - "contract_name": "ArbitrationPolicyUMA", + "contract_name": "ArbitrationPolicyUMA", "contract_address": "0xfFD98c3877B8789124f02C7E8239A4b0Ef11E936", "functions": [ "minLiveness", diff --git a/src/story_protocol_python_sdk/scripts/generate_clients.py b/src/story_protocol_python_sdk/scripts/generate_clients.py index 5eb14a2..132f828 100644 --- a/src/story_protocol_python_sdk/scripts/generate_clients.py +++ b/src/story_protocol_python_sdk/scripts/generate_clients.py @@ -1,5 +1,6 @@ import json import os + from jinja2 import Template # Define the folder containing the ABI JSON files @@ -36,7 +37,7 @@ def {{ function.python_name }}(self{% if function.inputs %}, {{ function.inputs 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.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 %} @@ -64,7 +65,7 @@ def {{ function.python_name }}(self{% if function.inputs %}, {{ function.inputs 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.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 %} diff --git a/src/story_protocol_python_sdk/story_client.py b/src/story_protocol_python_sdk/story_client.py index 410881c..652ce1f 100644 --- a/src/story_protocol_python_sdk/story_client.py +++ b/src/story_protocol_python_sdk/story_client.py @@ -3,22 +3,22 @@ import os import sys +from story_protocol_python_sdk.resources.Dispute import Dispute +from story_protocol_python_sdk.resources.Group import Group +from story_protocol_python_sdk.resources.IPAccount import IPAccount +from story_protocol_python_sdk.resources.IPAsset import IPAsset +from story_protocol_python_sdk.resources.License import License +from story_protocol_python_sdk.resources.NFTClient import NFTClient +from story_protocol_python_sdk.resources.Permission import Permission +from story_protocol_python_sdk.resources.Royalty import Royalty +from story_protocol_python_sdk.resources.WIP import WIP + # Ensure the src directory is in the Python path current_dir = os.path.dirname(__file__) src_path = os.path.abspath(os.path.join(current_dir, "..")) if src_path not in sys.path: sys.path.append(src_path) -from story_protocol_python_sdk.resources.IPAsset import IPAsset -from story_protocol_python_sdk.resources.License import License -from story_protocol_python_sdk.resources.Royalty import Royalty -from story_protocol_python_sdk.resources.IPAccount import IPAccount -from story_protocol_python_sdk.resources.Permission import Permission -from story_protocol_python_sdk.resources.NFTClient import NFTClient -from story_protocol_python_sdk.resources.Dispute import Dispute -from story_protocol_python_sdk.resources.WIP import WIP -from story_protocol_python_sdk.resources.Group import Group - class StoryClient: """ diff --git a/src/story_protocol_python_sdk/utils/ipfs.py b/src/story_protocol_python_sdk/utils/ipfs.py index 8914d93..0318db3 100644 --- a/src/story_protocol_python_sdk/utils/ipfs.py +++ b/src/story_protocol_python_sdk/utils/ipfs.py @@ -1,5 +1,4 @@ import base58 -from typing import Union V0_PREFIX = "1220" @@ -15,7 +14,7 @@ def convert_cid_to_hash_ipfs(cid: str) -> str: Hex string starting with '0x' """ # Check if CID is v0 (starts with "Qm") - is_v0 = cid.startswith("Qm") + cid.startswith("Qm") # Decode base58 CID bytes_array = base58.b58decode(cid) diff --git a/src/story_protocol_python_sdk/utils/license_terms.py b/src/story_protocol_python_sdk/utils/license_terms.py index cef571f..5597e55 100644 --- a/src/story_protocol_python_sdk/utils/license_terms.py +++ b/src/story_protocol_python_sdk/utils/license_terms.py @@ -5,7 +5,7 @@ from story_protocol_python_sdk.abi.RoyaltyModule.RoyaltyModule_client import ( RoyaltyModuleClient, ) -from story_protocol_python_sdk.utils.constants import ZERO_ADDRESS, ROYALTY_POLICY +from story_protocol_python_sdk.utils.constants import ROYALTY_POLICY, ZERO_ADDRESS class LicenseTerms: diff --git a/src/story_protocol_python_sdk/utils/oov3.py b/src/story_protocol_python_sdk/utils/oov3.py index 5900212..ee5b3b7 100644 --- a/src/story_protocol_python_sdk/utils/oov3.py +++ b/src/story_protocol_python_sdk/utils/oov3.py @@ -2,7 +2,9 @@ # Load the ABI from the JSON file import json import os + from web3 import Web3 + from story_protocol_python_sdk.abi.ArbitrationPolicyUMA.ArbitrationPolicyUMA_client import ( ArbitrationPolicyUMAClient, ) diff --git a/src/story_protocol_python_sdk/utils/sign.py b/src/story_protocol_python_sdk/utils/sign.py index 88bcc4d..0fe266c 100644 --- a/src/story_protocol_python_sdk/utils/sign.py +++ b/src/story_protocol_python_sdk/utils/sign.py @@ -1,19 +1,18 @@ # src/story_protcol_python_sdk/utils/sign.py -from web3 import Web3 +from datetime import datetime + +from eth_abi.abi import encode from eth_account import Account from eth_account.messages import encode_typed_data -from eth_abi.abi import encode -from datetime import datetime +from web3 import Web3 -from story_protocol_python_sdk.abi.IPAccountImpl.IPAccountImpl_client import ( - IPAccountImplClient, -) from story_protocol_python_sdk.abi.AccessController.AccessController_client import ( AccessControllerClient, ) - -from story_protocol_python_sdk.utils.constants import ZERO_FUNC +from story_protocol_python_sdk.abi.IPAccountImpl.IPAccountImpl_client import ( + IPAccountImplClient, +) class Sign: diff --git a/tests/demo/demo.py b/tests/demo/demo.py index 28f1557..e126c1c 100644 --- a/tests/demo/demo.py +++ b/tests/demo/demo.py @@ -1,17 +1,17 @@ import os -from dotenv import load_dotenv -from web3 import Web3 -from story_protocol_python_sdk import StoryClient from demo_utils import ( - get_token_id, - MockERC721, + PIL_LICENSE_TEMPLATE, + ROYALTY_POLICY, MockERC20, + MockERC721, + get_token_id, mint_tokens, - ROYALTY_POLICY, - ROYALTY_MODULE, - PIL_LICENSE_TEMPLATE, ) +from dotenv import load_dotenv +from web3 import Web3 + +from story_protocol_python_sdk import StoryClient def main(): @@ -69,13 +69,13 @@ def main(): print( f"Attached License Terms to IP at transaction hash {attach_license_terms_response['txHash']}" ) - except Exception as e: + except Exception: print( f"License Terms ID {register_pil_terms_response['licenseTermsId']} already attached to this IPA." ) # Before you mint make sure you have enough ERC20 tokens according to the minting fee above - token_ids = mint_tokens(MockERC20, web3, account, account.address, 10000) + mint_tokens(MockERC20, web3, account, account.address, 10000) # 5. Mint License mint_license_response = story_client.License.mintLicenseTokens( diff --git a/tests/integration/setup_for_integration.py b/tests/integration/setup_for_integration.py index 3aecdce..872d2d3 100644 --- a/tests/integration/setup_for_integration.py +++ b/tests/integration/setup_for_integration.py @@ -1,38 +1,37 @@ import os import sys + import pytest from dotenv import load_dotenv -from web3 import Web3 - -# Ensure the src directory is in the Python path -current_dir = os.path.dirname(__file__) -src_path = os.path.abspath(os.path.join(current_dir, "..", "..")) -if src_path not in sys.path: - sys.path.append(src_path) # Import everything from utils from utils import ( - get_story_client_in_devnet, - get_token_id, - mint_tokens, - approve, - get_block_timestamp, - check_event_in_tx, - MockERC721, - MockERC20, - ZERO_ADDRESS, - ROYALTY_POLICY, - ROYALTY_MODULE, - PIL_LICENSE_TEMPLATE, ARBITRATION_POLICY_UMA, - generate_cid, - WIP_TOKEN_ADDRESS, - setup_royalty_vault, EVEN_SPLIT_GROUP_POOL, + PIL_LICENSE_TEMPLATE, ROYALTY_POLICY_LRP, - CORE_METADATA_MODULE, + WIP_TOKEN_ADDRESS, + ZERO_ADDRESS, + MockERC20, + MockERC721, + approve, + check_event_in_tx, + generate_cid, + get_block_timestamp, + get_story_client_in_devnet, + get_token_id, mint_by_spg, + mint_tokens, + setup_royalty_vault, ) +from web3 import Web3 + +# Ensure the src directory is in the Python path +current_dir = os.path.dirname(__file__) +src_path = os.path.abspath(os.path.join(current_dir, "..", "..")) +if src_path not in sys.path: + sys.path.append(src_path) + # Load environment variables load_dotenv(override=True) @@ -81,7 +80,6 @@ def story_client_2(): "MockERC721", "MockERC20", "ZERO_ADDRESS", - "ROYALTY_POLICY" "ROYALTY_MODULE", "PIL_LICENSE_TEMPLATE", "ARBITRATION_POLICY_UMA", "account_2", diff --git a/tests/integration/test_integration_dispute.py b/tests/integration/test_integration_dispute.py index d489697..9175ea6 100644 --- a/tests/integration/test_integration_dispute.py +++ b/tests/integration/test_integration_dispute.py @@ -1,19 +1,9 @@ # tests/integration/test_integration_dispute.py import pytest +from setup_for_integration import account, generate_cid, web3 from web3 import Web3 -from setup_for_integration import ( - web3, - account, - account_2, - story_client, - story_client_2, - generate_cid, - approve, - wallet_address, -) - class TestDispute: @pytest.fixture(scope="module") @@ -82,9 +72,7 @@ def test_counter_dispute( # Generate a CID for counter evidence counter_evidence_cid = generate_cid() - deposit_response_2 = story_client_2.WIP.deposit( - amount=Web3.to_wei(1, "ether") # 1 IP - ) + story_client_2.WIP.deposit(amount=Web3.to_wei(1, "ether")) # 1 IP # Counter the dispute assertion with story_client_2 (the IP owner) response = story_client_2.Dispute.dispute_assertion( diff --git a/tests/integration/test_integration_group.py b/tests/integration/test_integration_group.py index a838e63..91f47cb 100644 --- a/tests/integration/test_integration_group.py +++ b/tests/integration/test_integration_group.py @@ -1,20 +1,16 @@ # tests/integration/test_integration_group.py -import pytest -from web3 import Web3 import copy +import pytest from setup_for_integration import ( - web3, - account, - story_client, - get_token_id, - MockERC721, - MockERC20, - ZERO_ADDRESS, - PIL_LICENSE_TEMPLATE, EVEN_SPLIT_GROUP_POOL, + PIL_LICENSE_TEMPLATE, ROYALTY_POLICY_LRP, + ZERO_ADDRESS, + MockERC20, + account, + web3, ) # class TestGroupBasicOperations: diff --git a/tests/integration/test_integration_ip_account.py b/tests/integration/test_integration_ip_account.py index 1cc13a7..0fd2f58 100644 --- a/tests/integration/test_integration_ip_account.py +++ b/tests/integration/test_integration_ip_account.py @@ -1,22 +1,20 @@ # tests/integration/test_integration_ip_account.py import pytest -from web3 import Web3 +from eth_abi.abi import encode from eth_account import Account from eth_account.messages import encode_typed_data -from eth_abi.abi import encode - from setup_for_integration import ( - web3, + MockERC20, + MockERC721, account, - story_client, + get_block_timestamp, get_token_id, mint_tokens, - get_block_timestamp, - MockERC721, - MockERC20, private_key, + web3, ) +from web3 import Web3 class TestBasicIPAccountOperations: @@ -433,7 +431,7 @@ def test_transfer_erc20(self, story_client): # 2. Transfer ERC20 tokens to the IP account amount_to_mint = 2000000 # Equivalent to 0.002 ether in wei - mint_receipt = mint_tokens( + mint_tokens( erc20_contract_address=MockERC20, web3=story_client.web3, account=story_client.account, @@ -443,7 +441,7 @@ def test_transfer_erc20(self, story_client): # 3. Transfer WIP to the IP account # First deposit (wrap) IP to WIP - deposit_response = story_client.WIP.deposit(amount=1) + story_client.WIP.deposit(amount=1) # Then transfer WIP to the IP account response = story_client.WIP.transfer(to=ip_id, amount=1) @@ -502,7 +500,7 @@ def test_transfer_erc20_empty_tokens(self, story_client): ip_id = register_response["ip_id"] # Try to transfer with empty tokens list - with pytest.raises(Exception) as exc_info: + with pytest.raises(Exception): story_client.IPAccount.transfer_erc20( ip_id=ip_id, tokens=[] # Empty tokens list ) diff --git a/tests/integration/test_integration_ip_asset.py b/tests/integration/test_integration_ip_asset.py index b92def1..e10f0b1 100644 --- a/tests/integration/test_integration_ip_asset.py +++ b/tests/integration/test_integration_ip_asset.py @@ -1,20 +1,17 @@ # tests/integration/test_integration_ip_asset.py import pytest -from web3 import Web3 - from setup_for_integration import ( - web3, - account, - story_client, - get_token_id, - MockERC721, - MockERC20, - ZERO_ADDRESS, - ROYALTY_POLICY, PIL_LICENSE_TEMPLATE, + ROYALTY_POLICY, WIP_TOKEN_ADDRESS, + ZERO_ADDRESS, + MockERC20, + MockERC721, + account, + get_token_id, mint_by_spg, + web3, ) @@ -97,7 +94,7 @@ def parent_ip_id(self, story_client, non_commercial_license): nft_contract=MockERC721, token_id=token_id ) - attach_license_response = story_client.License.attach_license_terms( + story_client.License.attach_license_terms( response["ip_id"], PIL_LICENSE_TEMPLATE, non_commercial_license ) @@ -240,7 +237,7 @@ def test_mint_register_ip(self, story_client, nft_collection): ), } - response = story_client.IPAsset.mint_and_register_ip( + 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 5f1c104..1532af2 100644 --- a/tests/integration/test_integration_license.py +++ b/tests/integration/test_integration_license.py @@ -1,21 +1,17 @@ # tests/integration/test_integration_license.py import pytest -from web3 import Web3 - from setup_for_integration import ( - web3, + PIL_LICENSE_TEMPLATE, + ROYALTY_MODULE, + ROYALTY_POLICY, + MockERC20, + MockERC721, account, - story_client, + approve, get_token_id, mint_tokens, - approve, - MockERC721, - MockERC20, - ZERO_ADDRESS, - ROYALTY_POLICY, - ROYALTY_MODULE, - PIL_LICENSE_TEMPLATE, + web3, ) @@ -116,7 +112,7 @@ def ip_id(story_client): response = story_client.IPAsset.register(nft_contract=MockERC721, token_id=token_id) - token_ids = mint_tokens( + mint_tokens( erc20_contract_address=MockERC20, web3=web3, account=account, @@ -124,7 +120,7 @@ def ip_id(story_client): amount=100000 * 10**6, ) - receipt = approve( + approve( erc20_contract_address=MockERC20, web3=web3, account=account, diff --git a/tests/integration/test_integration_nft_client.py b/tests/integration/test_integration_nft_client.py index 2c2fa26..9805f42 100644 --- a/tests/integration/test_integration_nft_client.py +++ b/tests/integration/test_integration_nft_client.py @@ -1,14 +1,9 @@ # tests/integration/test_integration_nft_client.py import pytest +from setup_for_integration import MockERC20 from web3 import Web3 -from setup_for_integration import ( - story_client, - MockERC721, - MockERC20, -) - class TestNFTCollectionOperations: """Tests for NFT collection creation and management""" @@ -153,7 +148,7 @@ def test_invalid_mint_fee_values(self, story_client): def test_parameter_omission(self, story_client): """Test omitting required parameters""" - with pytest.raises(TypeError) as exc_info: + with pytest.raises(TypeError): story_client.NFTClient.create_nft_collection( # name is omitted symbol="TEST", @@ -163,7 +158,7 @@ def test_parameter_omission(self, story_client): mint_fee_recipient=story_client.account.address, ) - with pytest.raises(TypeError) as exc_info: + with pytest.raises(TypeError): story_client.NFTClient.create_nft_collection( name="test-collection", # symbol is omitted @@ -173,7 +168,7 @@ def test_parameter_omission(self, story_client): mint_fee_recipient=story_client.account.address, ) - with pytest.raises(TypeError) as exc_info: + with pytest.raises(TypeError): story_client.NFTClient.create_nft_collection( name="test-collection", symbol="TEST", @@ -183,7 +178,7 @@ def test_parameter_omission(self, story_client): mint_fee_recipient=story_client.account.address, ) - with pytest.raises(TypeError) as exc_info: + with pytest.raises(TypeError): story_client.NFTClient.create_nft_collection( name="test-collection", symbol="TEST", @@ -193,7 +188,7 @@ def test_parameter_omission(self, story_client): mint_fee_recipient=story_client.account.address, ) - with pytest.raises(TypeError) as exc_info: + with pytest.raises(TypeError): story_client.NFTClient.create_nft_collection( name="test-collection", symbol="TEST", @@ -203,7 +198,7 @@ def test_parameter_omission(self, story_client): mint_fee_recipient=story_client.account.address, ) - with pytest.raises(TypeError) as exc_info: + with pytest.raises(TypeError): story_client.NFTClient.create_nft_collection( name="test-collection", symbol="TEST", diff --git a/tests/integration/test_integration_permission.py b/tests/integration/test_integration_permission.py index a82aa4d..a8c86ea 100644 --- a/tests/integration/test_integration_permission.py +++ b/tests/integration/test_integration_permission.py @@ -1,15 +1,12 @@ # tests/integration/test_integration_permission.py import pytest -from web3 import Web3 - from setup_for_integration import ( - web3, + CORE_METADATA_MODULE, + MockERC721, account, - story_client, get_token_id, - MockERC721, - CORE_METADATA_MODULE, + web3, ) diff --git a/tests/integration/test_integration_royalty.py b/tests/integration/test_integration_royalty.py index 5cfdcfe..4fadfc0 100644 --- a/tests/integration/test_integration_royalty.py +++ b/tests/integration/test_integration_royalty.py @@ -1,22 +1,20 @@ # tests/integration/test_integration_royalty.py -import pytest -from web3 import Web3 import copy +import pytest from setup_for_integration import ( - web3, + PIL_LICENSE_TEMPLATE, + ROYALTY_MODULE, + ROYALTY_POLICY, + ZERO_ADDRESS, + MockERC20, + MockERC721, account, - story_client, + approve, get_token_id, mint_tokens, - approve, - MockERC721, - MockERC20, - ZERO_ADDRESS, - ROYALTY_POLICY, - ROYALTY_MODULE, - PIL_LICENSE_TEMPLATE, + web3, ) @@ -387,7 +385,7 @@ def setup_claim_all_revenue_claim_options(self, story_client): spg_nft_contract=spg_nft_contract, ip_metadata=metadata_b ) ip_b = ip_b_response["ip_id"] - ip_b_derivative_response = story_client.IPAsset.register_derivative( + story_client.IPAsset.register_derivative( child_ip_id=ip_b, parent_ip_ids=[ip_a], license_terms_ids=[license_terms_id] ) diff --git a/tests/integration/test_integration_wip.py b/tests/integration/test_integration_wip.py index 51dae43..b16a576 100644 --- a/tests/integration/test_integration_wip.py +++ b/tests/integration/test_integration_wip.py @@ -1,10 +1,8 @@ # tests/integration/test_integration_wip.py -import pytest +from setup_for_integration import wallet_address, wallet_address_2, web3 from web3 import Web3 -from setup_for_integration import web3, story_client, wallet_address, wallet_address_2 - class TestWIPDeposit: def test_deposit(self, story_client): diff --git a/tests/integration/utils.py b/tests/integration/utils.py index 24eef74..159a6af 100644 --- a/tests/integration/utils.py +++ b/tests/integration/utils.py @@ -1,9 +1,11 @@ -from web3 import Web3 -from dotenv import load_dotenv -from src.story_protocol_python_sdk.story_client import StoryClient -import os import hashlib +import os + import base58 +from dotenv import load_dotenv +from web3 import Web3 + +from src.story_protocol_python_sdk.story_client import StoryClient load_dotenv() diff --git a/tests/unit/fixtures/web3.py b/tests/unit/fixtures/web3.py index aa33b40..6817f8e 100644 --- a/tests/unit/fixtures/web3.py +++ b/tests/unit/fixtures/web3.py @@ -1,8 +1,8 @@ -from web3 import Web3 from unittest.mock import MagicMock, Mock -from tests.unit.fixtures.data import ADDRESS +from web3 import Web3 +from tests.unit.fixtures.data import ADDRESS mock_web3 = Mock(spec=Web3) mock_web3.to_checksum_address = MagicMock(return_value=ADDRESS) diff --git a/tests/unit/resources/test_ip_account.py b/tests/unit/resources/test_ip_account.py index 3317511..3548279 100644 --- a/tests/unit/resources/test_ip_account.py +++ b/tests/unit/resources/test_ip_account.py @@ -1,10 +1,12 @@ import os import sys +from unittest.mock import MagicMock, patch + import pytest -from unittest.mock import patch, MagicMock -from web3 import Web3 -from web3.exceptions import InvalidAddress from eth_utils import is_address, to_checksum_address +from web3 import Web3 + +from src.story_protocol_python_sdk.resources.IPAccount import IPAccount # Ensure the src directory is in the Python path current_dir = os.path.dirname(__file__) @@ -12,8 +14,6 @@ if src_path not in sys.path: sys.path.append(src_path) -from src.story_protocol_python_sdk.resources.IPAccount import IPAccount - # Constants ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" ZERO_HASH = "0x0000000000000000000000000000000000000000000000000000000000000000" diff --git a/tests/unit/resources/test_ip_asset.py b/tests/unit/resources/test_ip_asset.py index 7c041df..1d3fb09 100644 --- a/tests/unit/resources/test_ip_asset.py +++ b/tests/unit/resources/test_ip_asset.py @@ -1,16 +1,18 @@ import os import sys +from unittest.mock import MagicMock, patch + import pytest -from unittest.mock import patch, MagicMock -from web3 import Web3 from eth_utils import is_address, to_checksum_address +from web3 import Web3 + +from src.story_protocol_python_sdk.resources.IPAsset import IPAsset current_dir = os.path.dirname(__file__) src_path = os.path.abspath(os.path.join(current_dir, "..", "..", "..")) if src_path not in sys.path: sys.path.append(src_path) -from src.story_protocol_python_sdk.resources.IPAsset import IPAsset ZERO_HASH = "0x0000000000000000000000000000000000000000000000000000000000000000" ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" diff --git a/tests/unit/resources/test_license.py b/tests/unit/resources/test_license.py index 259e43c..25470c9 100644 --- a/tests/unit/resources/test_license.py +++ b/tests/unit/resources/test_license.py @@ -1,17 +1,18 @@ -import logging -import pytest -from unittest.mock import patch, MagicMock -from web3 import Web3 import os import sys +from unittest.mock import MagicMock, patch + +import pytest from eth_utils import is_address, to_checksum_address +from web3 import Web3 + +from src.story_protocol_python_sdk.resources.License import License current_dir = os.path.dirname(__file__) src_path = os.path.abspath(os.path.join(current_dir, "..", "..", "..")) if src_path not in sys.path: sys.path.append(src_path) -from src.story_protocol_python_sdk.resources.License import License ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" VALID_ADDRESS = "0x1daAE3197Bc469Cb97B917aa460a12dD95c6627c" diff --git a/tests/unit/resources/test_permission.py b/tests/unit/resources/test_permission.py index eb7b9c5..9b0687b 100644 --- a/tests/unit/resources/test_permission.py +++ b/tests/unit/resources/test_permission.py @@ -1,8 +1,9 @@ -import pytest from unittest.mock import Mock, patch +import pytest + from story_protocol_python_sdk.resources.Permission import Permission -from tests.unit.fixtures.data import CHAIN_ID, ADDRESS, CHAIN_ID, STATE, TX_HASH +from tests.unit.fixtures.data import ADDRESS, CHAIN_ID, STATE, TX_HASH from tests.unit.fixtures.web3 import mock_web3 diff --git a/tests/unit/resources/test_royalty.py b/tests/unit/resources/test_royalty.py index d4c901d..a01b567 100644 --- a/tests/unit/resources/test_royalty.py +++ b/tests/unit/resources/test_royalty.py @@ -1,18 +1,21 @@ -import pytest, os, sys -from unittest.mock import patch, MagicMock +import os +import sys +from unittest.mock import patch + +import pytest + +# Load environment variables from .env file +from dotenv import load_dotenv from web3 import Web3 +from src.story_protocol_python_sdk.resources.Royalty import Royalty + # Ensure the src directory is in the Python path current_dir = os.path.dirname(__file__) src_path = os.path.abspath(os.path.join(current_dir, "..", "..", "..")) if src_path not in sys.path: sys.path.append(src_path) -from src.story_protocol_python_sdk.resources.Royalty import Royalty - -# Load environment variables from .env file -from dotenv import load_dotenv - load_dotenv() private_key = os.getenv("WALLET_PRIVATE_KEY") rpc_url = os.getenv("RPC_PROVIDER_URL") diff --git a/tests/unit/test_story_client.py b/tests/unit/test_story_client.py index afb0c23..455243e 100644 --- a/tests/unit/test_story_client.py +++ b/tests/unit/test_story_client.py @@ -1,15 +1,15 @@ import os -import sys + import pytest -from web3 import Web3 from dotenv import load_dotenv +from web3 import Web3 -from story_protocol_python_sdk.story_client import StoryClient +from story_protocol_python_sdk.resources.IPAccount import IPAccount from story_protocol_python_sdk.resources.IPAsset import IPAsset from story_protocol_python_sdk.resources.License import License -from story_protocol_python_sdk.resources.Royalty import Royalty -from story_protocol_python_sdk.resources.IPAccount import IPAccount from story_protocol_python_sdk.resources.Permission import Permission +from story_protocol_python_sdk.resources.Royalty import Royalty +from story_protocol_python_sdk.story_client import StoryClient from tests.unit.fixtures.data import CHAIN_ID # Load environment variables from .env file From 6e3ae41a37c4445380d90cf70f6a8ad1a7b5d8ef Mon Sep 17 00:00:00 2001 From: Bonnie Date: Mon, 4 Aug 2025 11:30:23 +0800 Subject: [PATCH 06/12] refactor: reorder import statements in setup.py for consistency --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index bf76f4f..eabcc7d 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,4 @@ -from setuptools import setup, find_packages +from setuptools import find_packages, setup # python setup.py sdist # twine upload dist/* From 12cd7695cd1bfc01e9445c664ce435ce0561d365 Mon Sep 17 00:00:00 2001 From: Bonnie Date: Mon, 4 Aug 2025 16:58:58 +0800 Subject: [PATCH 07/12] Added new `__init__.py` files to make `tests/integration` and `tests/integration/config` directories Python packages. --- tests/integration/__init__.py | 2 ++ tests/integration/config/__init__.py | 1 + 2 files changed, 3 insertions(+) create mode 100644 tests/integration/__init__.py create mode 100644 tests/integration/config/__init__.py diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py new file mode 100644 index 0000000..c66b545 --- /dev/null +++ b/tests/integration/__init__.py @@ -0,0 +1,2 @@ +# This file makes tests/integration a Python package +# Now modules can be imported directly from the package diff --git a/tests/integration/config/__init__.py b/tests/integration/config/__init__.py new file mode 100644 index 0000000..4f51ab5 --- /dev/null +++ b/tests/integration/config/__init__.py @@ -0,0 +1 @@ +# This file makes tests/integration/config a Python package From dd2de6009651c55e4e889837d27c2b19c701a33b Mon Sep 17 00:00:00 2001 From: Bonnie Date: Mon, 4 Aug 2025 17:00:39 +0800 Subject: [PATCH 08/12] Introduced for shared fixtures in integration tests --- tests/integration/conftest.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 tests/integration/conftest.py diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py new file mode 100644 index 0000000..9ed11c2 --- /dev/null +++ b/tests/integration/conftest.py @@ -0,0 +1,17 @@ +import pytest + +from story_protocol_python_sdk.story_client import StoryClient +from tests.integration.config.test_config import account, account_2, web3 +from tests.integration.config.utils import get_story_client + + +@pytest.fixture(scope="session") +def story_client() -> StoryClient: + """Fixture to provide the main story client""" + return get_story_client(web3, account) + + +@pytest.fixture(scope="session") +def story_client_2() -> StoryClient: + """Fixture to provide the secondary story client""" + return get_story_client(web3, account_2) From 70dcdab9e8020c307e21026d10f09a62a5cbe652 Mon Sep 17 00:00:00 2001 From: Bonnie Date: Mon, 4 Aug 2025 17:01:10 +0800 Subject: [PATCH 09/12] Updated `pytest.ini` to include additional paths for test discovery. --- pytest.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pytest.ini b/pytest.ini index b7789cd..9ccddb9 100644 --- a/pytest.ini +++ b/pytest.ini @@ -9,3 +9,5 @@ addopts = -v -ra # ignore directories norecursedirs = *.egg .git .* _darcs build dist venv + +pythonpath = tests/integration tests/integration/config tests/unit tests/demo From b50f76e88fa67129e7a8bc647aeacd07575764aa Mon Sep 17 00:00:00 2001 From: Bonnie Date: Mon, 4 Aug 2025 17:01:43 +0800 Subject: [PATCH 10/12] Refactored `setup_for_integration.py` to streamline configuration loading and improve readability. --- tests/integration/setup_for_integration.py | 82 +++++++--------------- 1 file changed, 25 insertions(+), 57 deletions(-) diff --git a/tests/integration/setup_for_integration.py b/tests/integration/setup_for_integration.py index 872d2d3..c25f05e 100644 --- a/tests/integration/setup_for_integration.py +++ b/tests/integration/setup_for_integration.py @@ -1,14 +1,22 @@ -import os -import sys - -import pytest -from dotenv import load_dotenv +# Import configuration from test_config +from tests.integration.config.test_config import ( + account, + account_2, + private_key, + private_key_2, + wallet_address, + wallet_address_2, + web3, +) -# Import everything from utils -from utils import ( +# Import utilities +from tests.integration.config.utils import ( ARBITRATION_POLICY_UMA, + CORE_METADATA_MODULE, EVEN_SPLIT_GROUP_POOL, PIL_LICENSE_TEMPLATE, + ROYALTY_MODULE, + ROYALTY_POLICY, ROYALTY_POLICY_LRP, WIP_TOKEN_ADDRESS, ZERO_ADDRESS, @@ -18,60 +26,23 @@ check_event_in_tx, generate_cid, get_block_timestamp, - get_story_client_in_devnet, + get_story_client, get_token_id, mint_by_spg, mint_tokens, setup_royalty_vault, ) -from web3 import Web3 - -# Ensure the src directory is in the Python path -current_dir = os.path.dirname(__file__) -src_path = os.path.abspath(os.path.join(current_dir, "..", "..")) -if src_path not in sys.path: - sys.path.append(src_path) - - -# Load environment variables -load_dotenv(override=True) -private_key = os.getenv("WALLET_PRIVATE_KEY") -private_key_2 = os.getenv("WALLET_PRIVATE_KEY_2") -rpc_url = os.getenv("RPC_PROVIDER_URL") -wallet_address = os.getenv("WALLET_ADDRESS") -wallet_address_2 = os.getenv("WALLET_ADDRESS_2") - -if not private_key: - raise ValueError("WALLET_PRIVATE_KEY environment variable is not set") -if not rpc_url: - raise ValueError("RPC_PROVIDER_URL environment variable is not set") - -# Initialize Web3 -web3 = Web3(Web3.HTTPProvider(rpc_url)) -if not web3.is_connected(): - raise Exception("Failed to connect to Web3 provider") - -# Set up the account with the private key -account = web3.eth.account.from_key(private_key) -account_2 = web3.eth.account.from_key(private_key_2) - - -@pytest.fixture(scope="session") -def story_client(): - return get_story_client_in_devnet(web3, account) - -@pytest.fixture(scope="session") -def story_client_2(): - return get_story_client_in_devnet(web3, account_2) - - -# Export everything needed by test files +# Export all shared configuration __all__ = [ "web3", "account", "account_2", - "story_client", + "wallet_address", + "wallet_address_2", + "private_key", + "private_key_2", + "get_story_client", "get_token_id", "mint_tokens", "approve", @@ -80,18 +51,15 @@ def story_client_2(): "MockERC721", "MockERC20", "ZERO_ADDRESS", + "ROYALTY_POLICY", + "ROYALTY_MODULE", "PIL_LICENSE_TEMPLATE", "ARBITRATION_POLICY_UMA", - "account_2", - "story_client_2", "generate_cid", "setup_royalty_vault", "WIP_TOKEN_ADDRESS", - "wallet_address", - "wallet_address_2", - "private_key", - "private_key_2", "EVEN_SPLIT_GROUP_POOL", "ROYALTY_POLICY_LRP", "mint_by_spg", + "CORE_METADATA_MODULE", ] From 05a1e25c817ecfe0c542c1a866c3318584990095 Mon Sep 17 00:00:00 2001 From: Bonnie Date: Mon, 4 Aug 2025 17:02:30 +0800 Subject: [PATCH 11/12] Enhanced integration tests to utilize the new `StoryClient` fixture for better dependency management. --- tests/integration/config/test_config.py | 37 ++++++++++++ tests/integration/{ => config}/utils.py | 21 +------ tests/integration/test_integration_dispute.py | 20 ++++--- tests/integration/test_integration_group.py | 3 +- .../test_integration_ip_account.py | 36 +++++------ .../integration/test_integration_ip_asset.py | 59 +++++++++++-------- tests/integration/test_integration_license.py | 53 +++++++++++------ .../test_integration_nft_client.py | 29 +++++---- .../test_integration_permission.py | 25 ++++---- tests/integration/test_integration_royalty.py | 29 +++++---- tests/integration/test_integration_wip.py | 15 +++-- 11 files changed, 201 insertions(+), 126 deletions(-) create mode 100644 tests/integration/config/test_config.py rename tests/integration/{ => config}/utils.py (92%) diff --git a/tests/integration/config/test_config.py b/tests/integration/config/test_config.py new file mode 100644 index 0000000..8b3248d --- /dev/null +++ b/tests/integration/config/test_config.py @@ -0,0 +1,37 @@ +import os + +from dotenv import load_dotenv +from web3 import Web3 + +# Load environment variables +load_dotenv(override=True) +private_key = os.getenv("WALLET_PRIVATE_KEY") +private_key_2 = os.getenv("WALLET_PRIVATE_KEY_2") +rpc_url = os.getenv("RPC_PROVIDER_URL") +wallet_address = os.getenv("WALLET_ADDRESS") +wallet_address_2 = os.getenv("WALLET_ADDRESS_2") + +if not private_key: + raise ValueError("WALLET_PRIVATE_KEY environment variable is not set") +if not rpc_url: + raise ValueError("RPC_PROVIDER_URL environment variable is not set") + +# Initialize Web3 +web3 = Web3(Web3.HTTPProvider(rpc_url)) +if not web3.is_connected(): + raise Exception("Failed to connect to Web3 provider") + +# Set up the account with the private key +account = web3.eth.account.from_key(private_key) +account_2 = web3.eth.account.from_key(private_key_2) + +# Export all configuration +__all__ = [ + "web3", + "account", + "account_2", + "wallet_address", + "wallet_address_2", + "private_key", + "private_key_2", +] diff --git a/tests/integration/utils.py b/tests/integration/config/utils.py similarity index 92% rename from tests/integration/utils.py rename to tests/integration/config/utils.py index 159a6af..7464803 100644 --- a/tests/integration/utils.py +++ b/tests/integration/config/utils.py @@ -5,7 +5,7 @@ from dotenv import load_dotenv from web3 import Web3 -from src.story_protocol_python_sdk.story_client import StoryClient +from story_protocol_python_sdk.story_client import StoryClient load_dotenv() @@ -26,23 +26,8 @@ CORE_METADATA_MODULE = "0x6E81a25C99C6e8430aeC7353325EB138aFE5DC16" -def get_story_client_in_sepolia(web3: Web3, account) -> StoryClient: - chain_id = 11155111 # Sepolia chain ID - return StoryClient(web3, account, chain_id) - - -def get_story_client_in_iliad(web3: Web3, account) -> StoryClient: - chain_id = 1513 # Sepolia chain ID - return StoryClient(web3, account, chain_id) - - -def get_story_client_in_odyssey(web3: Web3, account) -> StoryClient: - chain_id = 1516 # Odyssey chain ID - return StoryClient(web3, account, chain_id) - - -def get_story_client_in_devnet(web3: Web3, account) -> StoryClient: - chain_id = 1315 # Devnet chain ID +def get_story_client(web3: Web3, account) -> StoryClient: + chain_id = 1315 # aeneid chain ID return StoryClient(web3, account, chain_id) diff --git a/tests/integration/test_integration_dispute.py b/tests/integration/test_integration_dispute.py index 9175ea6..fa3207a 100644 --- a/tests/integration/test_integration_dispute.py +++ b/tests/integration/test_integration_dispute.py @@ -1,13 +1,15 @@ # tests/integration/test_integration_dispute.py import pytest -from setup_for_integration import account, generate_cid, web3 -from web3 import Web3 + +from story_protocol_python_sdk.story_client import StoryClient + +from .setup_for_integration import account, generate_cid, web3 class TestDispute: @pytest.fixture(scope="module") - def target_ip_id(self, story_client, story_client_2): + def target_ip_id(self, story_client: StoryClient, story_client_2: StoryClient): """Create an IP to be disputed""" txData = story_client.NFTClient.create_nft_collection( name="test-collection", @@ -37,7 +39,7 @@ def target_ip_id(self, story_client, story_client_2): return response["ip_id"] @pytest.fixture(scope="module") - def dispute_id(self, story_client, target_ip_id): + def dispute_id(self, story_client: StoryClient, target_ip_id): cid = generate_cid() bond_amount = 1000000000000000000 # 1 ETH in wei @@ -58,12 +60,16 @@ def dispute_id(self, story_client, target_ip_id): return response["dispute_id"] - def test_raise_dispute(self, story_client, dispute_id): + def test_raise_dispute(self, story_client: StoryClient, dispute_id): """Test raising a dispute""" assert dispute_id is not None def test_counter_dispute( - self, story_client_2, story_client, target_ip_id, dispute_id + self, + story_client_2: StoryClient, + story_client: StoryClient, + target_ip_id, + dispute_id, ): """Test countering a dispute""" # Get the assertion ID from the dispute ID @@ -72,7 +78,7 @@ def test_counter_dispute( # Generate a CID for counter evidence counter_evidence_cid = generate_cid() - story_client_2.WIP.deposit(amount=Web3.to_wei(1, "ether")) # 1 IP + story_client_2.WIP.deposit(amount=web3.to_wei(1, "ether")) # 1 IP # Counter the dispute assertion with story_client_2 (the IP owner) response = story_client_2.Dispute.dispute_assertion( diff --git a/tests/integration/test_integration_group.py b/tests/integration/test_integration_group.py index 91f47cb..a60f790 100644 --- a/tests/integration/test_integration_group.py +++ b/tests/integration/test_integration_group.py @@ -3,7 +3,8 @@ import copy import pytest -from setup_for_integration import ( + +from .setup_for_integration import ( EVEN_SPLIT_GROUP_POOL, PIL_LICENSE_TEMPLATE, ROYALTY_POLICY_LRP, diff --git a/tests/integration/test_integration_ip_account.py b/tests/integration/test_integration_ip_account.py index 0fd2f58..4dca5c9 100644 --- a/tests/integration/test_integration_ip_account.py +++ b/tests/integration/test_integration_ip_account.py @@ -16,11 +16,13 @@ ) from web3 import Web3 +from story_protocol_python_sdk.story_client import StoryClient + class TestBasicIPAccountOperations: """Basic IP Account operations like execute and nonce retrieval""" - def test_execute(self, story_client): + def test_execute(self, story_client: StoryClient): token_id = get_token_id(MockERC721, story_client.web3, story_client.account) response = story_client.IPAsset.register( nft_contract=MockERC721, token_id=token_id @@ -32,7 +34,7 @@ def test_execute(self, story_client): response["ip_id"], account.address, "0x89630Ccf23277417FBdfd3076C702F5248267e78", - Web3.keccak(text="function setAll(address,string,bytes32,bytes32)")[:4], + web3.keccak(text="function setAll(address,string,bytes32,bytes32)")[:4], 1, ], ) @@ -52,7 +54,7 @@ def test_execute(self, story_client): 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): + def test_get_ip_account_nonce(self, story_client: StoryClient): """Test getting IP Account nonce.""" token_id = get_token_id(MockERC721, story_client.web3, story_client.account) register_response = story_client.IPAsset.register( @@ -65,7 +67,7 @@ def test_get_ip_account_nonce(self, story_client): assert state is not None assert isinstance(state, bytes) - def test_execute_with_encoded_data(self, story_client): + def test_execute_with_encoded_data(self, story_client: StoryClient): """Test execute with pre-encoded function data.""" token_id = get_token_id(MockERC721, story_client.web3, story_client.account) register_response = story_client.IPAsset.register( @@ -79,7 +81,7 @@ def test_execute_with_encoded_data(self, story_client): ip_id, account.address, "0x89630Ccf23277417FBdfd3076C702F5248267e78", - Web3.keccak(text="function execute(address,uint256,bytes,uint8)")[:4], + web3.keccak(text="function execute(address,uint256,bytes,uint8)")[:4], 1, ], ) @@ -100,7 +102,7 @@ def test_execute_with_encoded_data(self, story_client): class TestSignatureOperations: """Tests for operations involving signatures""" - def test_execute_with_sig(self, story_client): + def test_execute_with_sig(self, story_client: StoryClient): token_id = get_token_id(MockERC721, story_client.web3, story_client.account) response = story_client.IPAsset.register( nft_contract=MockERC721, token_id=token_id @@ -116,7 +118,7 @@ def test_execute_with_sig(self, story_client): ip_id, account.address, "0x6E81a25C99C6e8430aeC7353325EB138aFE5DC16", - Web3.keccak(text="function setAll(address,string,bytes32,bytes32)")[:4], + web3.keccak(text="function setAll(address,string,bytes32,bytes32)")[:4], 1, ], ) @@ -130,8 +132,8 @@ def test_execute_with_sig(self, story_client): ], ) - expected_state = Web3.keccak( - encode(["bytes32", "bytes"], [state, Web3.to_bytes(hexstr=execute_data)]) + expected_state = web3.keccak( + encode(["bytes32", "bytes"], [state, web3.to_bytes(hexstr=execute_data)]) ) domain_data = { @@ -177,7 +179,7 @@ def test_execute_with_sig(self, story_client): assert isinstance(response["tx_hash"], str) assert len(response["tx_hash"]) > 0 - def test_execute_with_sig_multiple_permissions(self, story_client): + def test_execute_with_sig_multiple_permissions(self, story_client: StoryClient): """Test execute_with_sig setting multiple permissions.""" token_id = get_token_id(MockERC721, story_client.web3, story_client.account) register_response = story_client.IPAsset.register( @@ -276,7 +278,7 @@ def test_execute_with_sig_multiple_permissions(self, story_client): class TestErrorCases: """Tests for error cases and validation""" - def test_execute_invalid_address(self, story_client): + def test_execute_invalid_address(self, story_client: StoryClient): """Test execute with invalid address should raise error.""" token_id = get_token_id(MockERC721, story_client.web3, story_client.account) register_response = story_client.IPAsset.register( @@ -294,7 +296,7 @@ def test_execute_invalid_address(self, story_client): assert "is not a valid address" in str(exc_info.value) - def test_execute_unregistered_ip(self, story_client): + def test_execute_unregistered_ip(self, story_client: StoryClient): """Test execute with unregistered IP should raise error.""" unregistered_ip = "0x1234567890123456789012345678901234567890" data = "0x" @@ -309,7 +311,7 @@ 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): + def test_execute_with_sig_wrong_signer(self, story_client: StoryClient): """Test execute_with_sig 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( @@ -383,7 +385,7 @@ def test_execute_with_sig_wrong_signer(self, story_client): class TestSetIpMetadata: """Tests for setting IP metadata""" - def test_set_ip_metadata(self, story_client): + def test_set_ip_metadata(self, story_client: StoryClient): token_id = get_token_id(MockERC721, story_client.web3, story_client.account) response = story_client.IPAsset.register( nft_contract=MockERC721, token_id=token_id @@ -407,7 +409,7 @@ def test_set_ip_metadata(self, story_client): class Testtransfer_erc20: """Tests for transferring ERC20 tokens""" - def test_transfer_erc20(self, story_client): + def test_transfer_erc20(self, story_client: StoryClient): """Test transferring ERC20 tokens""" token_id = get_token_id(MockERC721, story_client.web3, story_client.account) response = story_client.IPAsset.register( @@ -491,7 +493,7 @@ def test_transfer_erc20(self, story_client): 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): + def test_transfer_erc20_empty_tokens(self, story_client: StoryClient): """Test transfer_erc20 with empty tokens list.""" token_id = get_token_id(MockERC721, story_client.web3, story_client.account) register_response = story_client.IPAsset.register( @@ -505,7 +507,7 @@ def test_transfer_erc20_empty_tokens(self, story_client): ip_id=ip_id, tokens=[] # Empty tokens list ) - def test_transfer_erc20_invalid_token_params(self, story_client): + def test_transfer_erc20_invalid_token_params(self, story_client: StoryClient): """Test transfer_erc20 with invalid token parameters.""" token_id = get_token_id(MockERC721, story_client.web3, story_client.account) register_response = story_client.IPAsset.register( diff --git a/tests/integration/test_integration_ip_asset.py b/tests/integration/test_integration_ip_asset.py index e10f0b1..ff9a5a0 100644 --- a/tests/integration/test_integration_ip_asset.py +++ b/tests/integration/test_integration_ip_asset.py @@ -1,7 +1,10 @@ # tests/integration/test_integration_ip_asset.py import pytest -from setup_for_integration import ( + +from story_protocol_python_sdk.story_client import StoryClient + +from .setup_for_integration import ( PIL_LICENSE_TEMPLATE, ROYALTY_POLICY, WIP_TOKEN_ADDRESS, @@ -17,7 +20,7 @@ class TestIPAssetRegistration: @pytest.fixture(scope="module") - def child_ip_id(self, story_client): + def child_ip_id(self, story_client: StoryClient): token_id = get_token_id(MockERC721, story_client.web3, story_client.account) response = story_client.IPAsset.register( @@ -32,10 +35,10 @@ def child_ip_id(self, story_client): assert response["ip_id"] is not None return response["ip_id"] - def test_register_ip_asset(self, story_client, child_ip_id): + def test_register_ip_asset(self, story_client: StoryClient, child_ip_id): assert child_ip_id is not None - def test_register_ip_asset_with_metadata(self, story_client): + def test_register_ip_asset_with_metadata(self, story_client: StoryClient): token_id = get_token_id(MockERC721, story_client.web3, story_client.account) metadata = { "ip_metadata_uri": "test-uri", @@ -64,7 +67,7 @@ def test_register_ip_asset_with_metadata(self, story_client): class TestIPAssetDerivatives: @pytest.fixture(scope="module") - def child_ip_id(self, story_client): + def child_ip_id(self, story_client: StoryClient): token_id = get_token_id(MockERC721, story_client.web3, story_client.account) response = story_client.IPAsset.register( @@ -80,7 +83,7 @@ def child_ip_id(self, story_client): return response["ip_id"] @pytest.fixture(scope="module") - def non_commercial_license(self, story_client): + def non_commercial_license(self, story_client: StoryClient): license_register_response = ( story_client.License.register_non_com_social_remixing_pil() ) @@ -88,7 +91,7 @@ def non_commercial_license(self, story_client): return no_commercial_license_terms_id @pytest.fixture(scope="module") - def parent_ip_id(self, story_client, non_commercial_license): + def parent_ip_id(self, story_client: StoryClient, non_commercial_license): token_id = get_token_id(MockERC721, story_client.web3, story_client.account) response = story_client.IPAsset.register( nft_contract=MockERC721, token_id=token_id @@ -101,7 +104,11 @@ def parent_ip_id(self, story_client, non_commercial_license): return response["ip_id"] def test_register_derivative( - self, story_client, child_ip_id, parent_ip_id, non_commercial_license + self, + story_client: StoryClient, + child_ip_id, + parent_ip_id, + non_commercial_license, ): response = story_client.IPAsset.register_derivative( child_ip_id=child_ip_id, @@ -119,7 +126,7 @@ def test_register_derivative( assert len(response["tx_hash"]) > 0 def test_register_derivative_with_license_tokens( - self, story_client, parent_ip_id, non_commercial_license + self, story_client: StoryClient, parent_ip_id, non_commercial_license ): token_id = get_token_id(MockERC721, story_client.web3, story_client.account) child_response = story_client.IPAsset.register( @@ -153,7 +160,7 @@ def test_register_derivative_with_license_tokens( class TestIPAssetMinting: @pytest.fixture(scope="module") - def nft_collection(self, story_client): + def nft_collection(self, story_client: StoryClient): tx_data = story_client.NFTClient.create_nft_collection( name="test-collection", symbol="TEST", @@ -165,7 +172,9 @@ def nft_collection(self, story_client): ) return tx_data["nft_contract"] - def test_mint_register_attach_terms(self, story_client, nft_collection): + def test_mint_register_attach_terms( + self, story_client: StoryClient, nft_collection + ): metadata = { "ip_metadata_uri": "test-uri", "ip_metadata_hash": web3.to_hex(web3.keccak(text="test-metadata-hash")), @@ -227,7 +236,7 @@ def test_mint_register_attach_terms(self, story_client, nft_collection): 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): + def test_mint_register_ip(self, story_client: StoryClient, nft_collection): metadata = { "ip_metadata_uri": "test-uri", "ip_metadata_hash": web3.to_hex(web3.keccak(text="test-metadata-hash")), @@ -244,7 +253,7 @@ def test_mint_register_ip(self, story_client, nft_collection): class TestSPGNFTOperations: @pytest.fixture(scope="module") - def nft_collection(self, story_client): + def nft_collection(self, story_client: StoryClient): tx_data = story_client.NFTClient.create_nft_collection( name="test-collection", symbol="TEST", @@ -257,7 +266,7 @@ def nft_collection(self, story_client): return tx_data["nft_contract"] @pytest.fixture(scope="module") - def parent_ip_and_license_terms(self, story_client, nft_collection): + def parent_ip_and_license_terms(self, story_client: StoryClient, nft_collection): response = story_client.IPAsset.mint_and_register_ip_asset_with_pil_terms( spg_nft_contract=nft_collection, terms=[ @@ -339,7 +348,7 @@ def parent_ip_and_license_terms(self, story_client, nft_collection): # assert isinstance(result['ip_id'], str) and result['ip_id'] def test_register_ip_and_attach_pil_terms( - self, story_client, nft_collection, parent_ip_and_license_terms + self, story_client: StoryClient, nft_collection, parent_ip_and_license_terms ): token_id = mint_by_spg(nft_collection, story_client.web3, story_client.account) @@ -427,7 +436,7 @@ def test_register_ip_and_attach_pil_terms( class TestIPAssetMint: @pytest.fixture(scope="module") - def nft_collection(self, story_client): + def nft_collection(self, story_client: StoryClient): tx_data = story_client.NFTClient.create_nft_collection( name="test-mint-collection", symbol="MINT", @@ -439,7 +448,7 @@ def nft_collection(self, story_client): ) return tx_data["nft_contract"] - def test_mint_basic(self, story_client, nft_collection): + def test_mint_basic(self, story_client: StoryClient, nft_collection): """Test basic minting functionality""" metadata_uri = "https://example.com/metadata/1.json" metadata_hash = web3.keccak(text="test-metadata-content") @@ -461,7 +470,9 @@ def test_mint_basic(self, story_client, nft_collection): receipt = story_client.web3.eth.wait_for_transaction_receipt(response) assert receipt.status == 1 - def test_mint_with_duplicates_allowed(self, story_client, nft_collection): + def test_mint_with_duplicates_allowed( + self, story_client: StoryClient, nft_collection + ): """Test minting with duplicate metadata allowed""" metadata_uri = "https://example.com/metadata/duplicate.json" metadata_hash = web3.keccak(text="duplicate-metadata-content") @@ -495,7 +506,7 @@ def test_mint_with_duplicates_allowed(self, story_client, nft_collection): # Verify different transaction hashes assert response1 != response2 - def test_mint_to_different_address(self, story_client, nft_collection): + def test_mint_to_different_address(self, story_client: StoryClient, nft_collection): """Test minting to a different recipient address""" # Create a different recipient address for testing different_account = story_client.web3.eth.account.create() @@ -516,7 +527,9 @@ def test_mint_to_different_address(self, story_client, nft_collection): receipt = story_client.web3.eth.wait_for_transaction_receipt(response) assert receipt.status == 1 - def test_mint_with_various_metadata_formats(self, story_client, nft_collection): + def test_mint_with_various_metadata_formats( + self, story_client: StoryClient, nft_collection + ): """Test minting with different metadata URI formats""" test_cases = [ { @@ -546,7 +559,7 @@ def test_mint_with_various_metadata_formats(self, story_client, nft_collection): receipt = story_client.web3.eth.wait_for_transaction_receipt(response) assert receipt.status == 1 - def test_mint_with_zero_hash(self, story_client, nft_collection): + def test_mint_with_zero_hash(self, story_client: StoryClient, nft_collection): """Test minting with zero hash""" metadata_uri = "https://example.com/metadata/zero-hash.json" zero_hash = b"\x00" * 32 # 32 bytes of zeros @@ -563,7 +576,7 @@ def test_mint_with_zero_hash(self, story_client, nft_collection): receipt = story_client.web3.eth.wait_for_transaction_receipt(response) assert receipt.status == 1 - def test_mint_error_cases(self, story_client, nft_collection): + def test_mint_error_cases(self, story_client: StoryClient, nft_collection): """Test various error cases for minting""" metadata_uri = "https://example.com/metadata/error-test.json" metadata_hash = web3.keccak(text="error-test-metadata") @@ -599,7 +612,7 @@ def test_mint_error_cases(self, story_client, nft_collection): ) def test_mint_with_existing_metadata_hash_no_duplicates( - self, story_client, nft_collection + self, story_client: StoryClient, nft_collection ): """Test that minting with existing metadata hash fails when duplicates not allowed""" metadata_uri = "https://example.com/metadata/no-duplicates.json" diff --git a/tests/integration/test_integration_license.py b/tests/integration/test_integration_license.py index 1532af2..bcc5be9 100644 --- a/tests/integration/test_integration_license.py +++ b/tests/integration/test_integration_license.py @@ -1,7 +1,10 @@ # tests/integration/test_integration_license.py import pytest -from setup_for_integration import ( + +from story_protocol_python_sdk.story_client import StoryClient + +from .setup_for_integration import ( PIL_LICENSE_TEMPLATE, ROYALTY_MODULE, ROYALTY_POLICY, @@ -15,7 +18,7 @@ ) -def test_register_pil_terms(story_client): +def test_register_pil_terms(story_client: StoryClient): response = story_client.License.register_pil_terms( transferable=False, royalty_policy=story_client.web3.to_checksum_address( @@ -46,7 +49,7 @@ def test_register_pil_terms(story_client): assert isinstance(response["license_terms_id"], int) -def test_register_non_com_social_remixing_pil(story_client): +def test_register_non_com_social_remixing_pil(story_client: StoryClient): response = story_client.License.register_non_com_social_remixing_pil() assert response is not None @@ -56,7 +59,7 @@ def test_register_non_com_social_remixing_pil(story_client): @pytest.fixture(scope="module") -def register_commercial_use_pil(story_client): +def register_commercial_use_pil(story_client: StoryClient): response = story_client.License.register_commercial_use_pil( default_minting_fee=11, currency=MockERC20, royalty_policy=ROYALTY_POLICY ) @@ -75,12 +78,14 @@ def register_commercial_use_pil(story_client): return response["license_terms_id"] -def test_register_commercial_use_pil(story_client, register_commercial_use_pil): +def test_register_commercial_use_pil( + story_client: StoryClient, register_commercial_use_pil +): assert register_commercial_use_pil is not None @pytest.fixture(scope="module") -def register_commercial_remix_pil(story_client): +def register_commercial_remix_pil(story_client: StoryClient): response = story_client.License.register_commercial_remix_pil( default_minting_fee=1, currency=MockERC20, @@ -102,12 +107,14 @@ def register_commercial_remix_pil(story_client): return response["license_terms_id"] -def test_register_commercial_remix_pil(story_client, register_commercial_remix_pil): +def test_register_commercial_remix_pil( + story_client: StoryClient, register_commercial_remix_pil +): assert register_commercial_remix_pil is not None @pytest.fixture(scope="module") -def ip_id(story_client): +def ip_id(story_client: StoryClient): token_id = get_token_id(MockERC721, story_client.web3, story_client.account) response = story_client.IPAsset.register(nft_contract=MockERC721, token_id=token_id) @@ -135,7 +142,9 @@ def ip_id(story_client): return response["ip_id"] -def test_attach_license_terms(story_client, ip_id, register_commercial_use_pil): +def test_attach_license_terms( + story_client: StoryClient, ip_id, register_commercial_use_pil +): license_terms_id = register_commercial_use_pil response = story_client.License.attach_license_terms( @@ -151,7 +160,9 @@ def test_attach_license_terms(story_client, ip_id, register_commercial_use_pil): assert len(response["tx_hash"]) > 0, "'tx_hash' is empty." -def test_mint_license_tokens(story_client, ip_id, register_commercial_use_pil): +def test_mint_license_tokens( + story_client: StoryClient, ip_id, register_commercial_use_pil +): response = story_client.License.mint_license_tokens( licensor_ip_id=ip_id, license_template=PIL_LICENSE_TEMPLATE, @@ -179,7 +190,7 @@ def test_mint_license_tokens(story_client, ip_id, register_commercial_use_pil): ), "Not all elements in 'license_token_ids' are integers." -def test_get_license_terms(story_client): +def test_get_license_terms(story_client: StoryClient): selectedLicenseTermsId = 3 response = story_client.License.get_license_terms(selectedLicenseTermsId) @@ -187,7 +198,9 @@ def test_get_license_terms(story_client): assert response is not None, "Response is None, indicating the call failed." -def test_predict_minting_license_fee(story_client, ip_id, register_commercial_use_pil): +def test_predict_minting_license_fee( + story_client: StoryClient, ip_id, register_commercial_use_pil +): response = story_client.License.predict_minting_license_fee( licensor_ip_id=ip_id, license_terms_id=register_commercial_use_pil, amount=1 ) @@ -204,7 +217,9 @@ def test_predict_minting_license_fee(story_client, ip_id, register_commercial_us assert isinstance(response["amount"], int), "'amount' is not an integer." -def test_set_licensing_config(story_client, ip_id, register_commercial_remix_pil): +def test_set_licensing_config( + story_client: StoryClient, ip_id, register_commercial_remix_pil +): licensing_config = { "mintingFee": 1, "isSet": True, @@ -234,7 +249,7 @@ def test_set_licensing_config(story_client, ip_id, register_commercial_remix_pil assert response["success"] is True, "'success' is not True" -def test_register_pil_terms_with_no_minting_fee(story_client): +def test_register_pil_terms_with_no_minting_fee(story_client: StoryClient): """Test registering PIL terms with no minting fee.""" response = story_client.License.register_pil_terms( transferable=False, @@ -266,7 +281,7 @@ def test_register_pil_terms_with_no_minting_fee(story_client): assert isinstance(response["license_terms_id"], int) -def test_register_commercial_use_pil_without_royalty_policy(story_client): +def test_register_commercial_use_pil_without_royalty_policy(story_client: StoryClient): """Test registering commercial use PIL without specifying royalty policy.""" response = story_client.License.register_commercial_use_pil( default_minting_fee=1, currency=MockERC20 @@ -279,7 +294,7 @@ def test_register_commercial_use_pil_without_royalty_policy(story_client): @pytest.fixture(scope="module") -def setup_license_terms(story_client, ip_id): +def setup_license_terms(story_client: StoryClient, ip_id): """Fixture to set up license terms for testing.""" response = story_client.License.register_commercial_remix_pil( default_minting_fee=1, @@ -297,7 +312,7 @@ def setup_license_terms(story_client, ip_id): return license_id -def test_multi_token_minting(story_client, ip_id, setup_license_terms): +def test_multi_token_minting(story_client: StoryClient, ip_id, setup_license_terms): """Test minting multiple license tokens at once.""" response = story_client.License.mint_license_tokens( licensor_ip_id=ip_id, @@ -318,7 +333,7 @@ def test_multi_token_minting(story_client, ip_id, setup_license_terms): def test_set_licensing_config_with_hooks( - story_client, ip_id, register_commercial_remix_pil + story_client: StoryClient, ip_id, register_commercial_remix_pil ): """Test setting licensing configuration with hooks enabled.""" licensing_config = { @@ -349,7 +364,7 @@ def test_set_licensing_config_with_hooks( def test_predict_minting_fee_with_multiple_tokens( - story_client, ip_id, setup_license_terms + story_client: StoryClient, ip_id, setup_license_terms ): """Test predicting minting fee for multiple tokens.""" response = story_client.License.predict_minting_license_fee( diff --git a/tests/integration/test_integration_nft_client.py b/tests/integration/test_integration_nft_client.py index 9805f42..e68b1c0 100644 --- a/tests/integration/test_integration_nft_client.py +++ b/tests/integration/test_integration_nft_client.py @@ -1,14 +1,17 @@ # tests/integration/test_integration_nft_client.py import pytest -from setup_for_integration import MockERC20 from web3 import Web3 +from story_protocol_python_sdk.story_client import StoryClient + +from .setup_for_integration import MockERC20 + class TestNFTCollectionOperations: """Tests for NFT collection creation and management""" - def test_create_basic_collection(self, story_client): + def test_create_basic_collection(self, story_client: StoryClient): """Test creating a basic NFT collection with minimum parameters""" response = story_client.NFTClient.create_nft_collection( name="test-collection", @@ -26,7 +29,7 @@ def test_create_basic_collection(self, story_client): assert "nft_contract" in response assert Web3.is_address(response["nft_contract"]) - def test_create_collection_with_supply(self, story_client): + def test_create_collection_with_supply(self, story_client: StoryClient): """Test creating collection with max supply""" response = story_client.NFTClient.create_nft_collection( name="test-collection", @@ -42,7 +45,7 @@ def test_create_collection_with_supply(self, story_client): assert "nft_contract" in response assert Web3.is_address(response["nft_contract"]) - def test_create_collection_with_mint_fee(self, story_client): + def test_create_collection_with_mint_fee(self, story_client: StoryClient): """Test creating collection with mint fee configuration""" response = story_client.NFTClient.create_nft_collection( name="test-collection", @@ -59,7 +62,7 @@ def test_create_collection_with_mint_fee(self, story_client): assert "nft_contract" in response assert Web3.is_address(response["nft_contract"]) - def test_create_collection_with_base_uri(self, story_client): + def test_create_collection_with_base_uri(self, story_client: StoryClient): """Test creating collection with base URI""" response = story_client.NFTClient.create_nft_collection( name="test-collection", @@ -79,7 +82,7 @@ def test_create_collection_with_base_uri(self, story_client): class TestErrorCases: """Tests for error handling in NFT collection creation""" - def test_invalid_mint_fee_configuration(self, story_client): + def test_invalid_mint_fee_configuration(self, story_client: StoryClient): """Test error when mint fee is set but token address is invalid""" with pytest.raises(ValueError) as exc_info: story_client.NFTClient.create_nft_collection( @@ -94,7 +97,7 @@ def test_invalid_mint_fee_configuration(self, story_client): ) assert "Invalid mint fee token address" in str(exc_info.value) - def test_invalid_recipient_address(self, story_client): + def test_invalid_recipient_address(self, story_client: StoryClient): """Test error when mint fee recipient address is invalid""" with pytest.raises(ValueError) as exc_info: story_client.NFTClient.create_nft_collection( @@ -110,7 +113,7 @@ def test_invalid_recipient_address(self, story_client): in str(exc_info.value).lower() ) - def test_invalid_mint_fee_values(self, story_client): + def test_invalid_mint_fee_values(self, story_client: StoryClient): """Test with invalid mint fee values""" with pytest.raises(ValueError) as exc_info: story_client.NFTClient.create_nft_collection( @@ -145,7 +148,7 @@ def test_invalid_mint_fee_values(self, story_client): or "invalid" in str(e).lower() ) - def test_parameter_omission(self, story_client): + def test_parameter_omission(self, story_client: StoryClient): """Test omitting required parameters""" with pytest.raises(TypeError): @@ -208,7 +211,7 @@ def test_parameter_omission(self, story_client): # mint_fee_recipient is omitted ) - def test_authorization_errors(self, story_client): + def test_authorization_errors(self, story_client: StoryClient): """Test unauthorized operations""" different_owner = "0x1234567890123456789012345678901234567890" @@ -232,7 +235,7 @@ class TestMintFee: """Tests for mint fee functionality in NFT collections""" @pytest.fixture(scope="module") - def nft_contract(self, story_client): + def nft_contract(self, story_client: StoryClient): response = story_client.NFTClient.create_nft_collection( name="paid-collection", symbol="PAID", @@ -247,12 +250,12 @@ def nft_contract(self, story_client): return response["nft_contract"] - def test_get_mint_fee_token(self, story_client, nft_contract): + def test_get_mint_fee_token(self, story_client: StoryClient, nft_contract): """Test successfully getting mint fee token""" 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): + def test_get_mint_fee(self, story_client: StoryClient, nft_contract): """Test successfully getting mint fee""" mint_fee = story_client.NFTClient.get_mint_fee(nft_contract) assert mint_fee == 1000 diff --git a/tests/integration/test_integration_permission.py b/tests/integration/test_integration_permission.py index a8c86ea..ae0e06e 100644 --- a/tests/integration/test_integration_permission.py +++ b/tests/integration/test_integration_permission.py @@ -1,7 +1,10 @@ # tests/integration/test_integration_permission.py import pytest -from setup_for_integration import ( + +from story_protocol_python_sdk.story_client import StoryClient + +from .setup_for_integration import ( CORE_METADATA_MODULE, MockERC721, account, @@ -12,7 +15,7 @@ class TestPermissions: @pytest.fixture(scope="class") - def ip_id(self, story_client): + def ip_id(self, story_client: StoryClient): """Fixture to create an IP for testing permissions.""" token_id = get_token_id(MockERC721, story_client.web3, story_client.account) response = story_client.IPAsset.register( @@ -21,7 +24,7 @@ def ip_id(self, story_client): assert "ip_id" in response, "Failed to register IP" return response["ip_id"] - def test_set_permission(self, story_client, ip_id): + def test_set_permission(self, story_client: StoryClient, ip_id): """Test setting permission successfully.""" response = story_client.Permission.set_permission( ip_id=ip_id, @@ -36,7 +39,7 @@ def test_set_permission(self, story_client, ip_id): assert isinstance(response["tx_hash"], str) assert len(response["tx_hash"]) > 0 - def test_set_all_permissions(self, story_client, ip_id): + def test_set_all_permissions(self, story_client: StoryClient, ip_id): """Test setting all permissions successfully.""" response = story_client.Permission.set_all_permissions( ip_id=ip_id, signer=account.address, permission=1 # ALLOW @@ -47,7 +50,7 @@ def test_set_all_permissions(self, story_client, ip_id): assert isinstance(response["tx_hash"], str) assert len(response["tx_hash"]) > 0 - def test_create_set_permission_signature(self, story_client, ip_id): + def test_create_set_permission_signature(self, story_client: StoryClient, ip_id): """Test creating set permission signature.""" deadline = web3.eth.get_block("latest")["timestamp"] + 60000 @@ -65,7 +68,7 @@ def test_create_set_permission_signature(self, story_client, ip_id): assert isinstance(response["tx_hash"], str) assert len(response["tx_hash"]) > 0 - def test_set_permission_invalid_ip(self, story_client): + def test_set_permission_invalid_ip(self, story_client: StoryClient): """Test setting permission for an unregistered IP.""" unregistered_ip = "0x1234567890123456789012345678901234567890" @@ -79,7 +82,7 @@ def test_set_permission_invalid_ip(self, story_client): assert f"IP id with {unregistered_ip} is not registered" in str(exc_info.value) - def test_set_permission_invalid_addresses(self, story_client, ip_id): + def test_set_permission_invalid_addresses(self, story_client: StoryClient, ip_id): """Test that set_permission raises proper exceptions for invalid addresses.""" invalid_signer = "0xinvalid_address" @@ -119,7 +122,7 @@ def test_set_permission_invalid_addresses(self, story_client, ip_id): f"set_permission should accept lowercase addresses, but raised: {e}" ) - def test_different_permission_levels(self, story_client, ip_id): + def test_different_permission_levels(self, story_client: StoryClient, ip_id): """Test setting and changing different permission levels.""" DISALLOW = 0 ALLOW = 1 @@ -174,7 +177,7 @@ def test_different_permission_levels(self, story_client, ip_id): assert response is not None assert "tx_hash" in response - def test_different_function_selectors(self, story_client, ip_id): + def test_different_function_selectors(self, story_client: StoryClient, ip_id): """Test setting permissions with different function selectors.""" ALLOW = 1 @@ -237,7 +240,9 @@ def test_different_function_selectors(self, story_client, ip_id): assert response is not None assert "tx_hash" in response - def test_permission_hierarchies_and_overrides(self, story_client, ip_id): + def test_permission_hierarchies_and_overrides( + self, story_client: StoryClient, ip_id + ): """Test permission hierarchies and how permissions override each other.""" DISALLOW = 0 ALLOW = 1 diff --git a/tests/integration/test_integration_royalty.py b/tests/integration/test_integration_royalty.py index 4fadfc0..262f8ec 100644 --- a/tests/integration/test_integration_royalty.py +++ b/tests/integration/test_integration_royalty.py @@ -3,7 +3,10 @@ import copy import pytest -from setup_for_integration import ( + +from story_protocol_python_sdk.story_client import StoryClient + +from .setup_for_integration import ( PIL_LICENSE_TEMPLATE, ROYALTY_MODULE, ROYALTY_POLICY, @@ -21,7 +24,7 @@ class TestRoyalty: @pytest.fixture(scope="module") - def setup_ips_and_licenses(self, story_client): + def setup_ips_and_licenses(self, story_client: StoryClient): """Setup parent and child IPs with proper license relationships""" parent_token_id = get_token_id( @@ -85,7 +88,9 @@ def setup_ips_and_licenses(self, story_client): "license_terms_id": license_terms_id, } - def test_pay_royalty_on_behalf(self, story_client, setup_ips_and_licenses): + def test_pay_royalty_on_behalf( + self, story_client: StoryClient, setup_ips_and_licenses + ): """Test paying royalty on behalf of a payer IP to a receiver IP""" parent_ip_id = setup_ips_and_licenses["parent_ip_id"] child_ip_id = setup_ips_and_licenses["child_ip_id"] @@ -100,7 +105,7 @@ def test_pay_royalty_on_behalf(self, story_client, setup_ips_and_licenses): assert response is not None assert response["tx_hash"] is not None and isinstance(response["tx_hash"], str) - def test_claimable_revenue(self, story_client, setup_ips_and_licenses): + def test_claimable_revenue(self, story_client: StoryClient, setup_ips_and_licenses): """Test checking claimable revenue""" parent_ip_id = setup_ips_and_licenses["parent_ip_id"] @@ -111,7 +116,7 @@ def test_claimable_revenue(self, story_client, setup_ips_and_licenses): assert isinstance(response, int) def test_pay_royalty_unregistered_receiver( - self, story_client, setup_ips_and_licenses + self, story_client: StoryClient, setup_ips_and_licenses ): """Test that paying royalty to unregistered IP fails appropriately""" child_ip_id = setup_ips_and_licenses["child_ip_id"] @@ -128,7 +133,9 @@ def test_pay_royalty_unregistered_receiver( amount=1000, ) - def test_pay_royalty_invalid_amount(self, story_client, setup_ips_and_licenses): + def test_pay_royalty_invalid_amount( + self, story_client: StoryClient, setup_ips_and_licenses + ): """Test that paying with invalid amount fails appropriately""" parent_ip_id = setup_ips_and_licenses["parent_ip_id"] child_ip_id = setup_ips_and_licenses["child_ip_id"] @@ -144,7 +151,7 @@ def test_pay_royalty_invalid_amount(self, story_client, setup_ips_and_licenses): class TestClaimAllRevenue: @pytest.fixture(scope="module") - def setup_claim_all_revenue(self, story_client): + def setup_claim_all_revenue(self, story_client: StoryClient): # Create NFT collection collection_response = story_client.NFTClient.create_nft_collection( name="free-collection", @@ -267,7 +274,9 @@ def setup_claim_all_revenue(self, story_client): return {"ip_a": ip_a, "ip_b": ip_b, "ip_c": ip_c, "ip_d": ip_d} - def test_claim_all_revenue(self, setup_claim_all_revenue, story_client): + def test_claim_all_revenue( + self, setup_claim_all_revenue, story_client: StoryClient + ): response = story_client.Royalty.claim_all_revenue( ancestor_ip_id=setup_claim_all_revenue["ip_a"], claimer=setup_claim_all_revenue["ip_a"], @@ -286,7 +295,7 @@ def test_claim_all_revenue(self, setup_claim_all_revenue, story_client): assert response["claimed_tokens"][0]["amount"] == 120 @pytest.fixture(scope="module") - def setup_claim_all_revenue_claim_options(self, story_client): + def setup_claim_all_revenue_claim_options(self, story_client: StoryClient): # Create NFT collection collection_response = story_client.NFTClient.create_nft_collection( name="free-collection", @@ -410,7 +419,7 @@ def setup_claim_all_revenue_claim_options(self, story_client): return {"ip_a": ip_a, "ip_b": ip_b, "ip_c": ip_c, "ip_d": ip_d} def test_claim_all_revenue_claim_options( - self, setup_claim_all_revenue_claim_options, story_client + self, setup_claim_all_revenue_claim_options, story_client: StoryClient ): """Test claiming all revenue with specific claim options""" response = story_client.Royalty.claim_all_revenue( diff --git a/tests/integration/test_integration_wip.py b/tests/integration/test_integration_wip.py index b16a576..b6d12b8 100644 --- a/tests/integration/test_integration_wip.py +++ b/tests/integration/test_integration_wip.py @@ -1,13 +1,12 @@ -# tests/integration/test_integration_wip.py +from story_protocol_python_sdk.story_client import StoryClient -from setup_for_integration import wallet_address, wallet_address_2, web3 -from web3 import Web3 +from .setup_for_integration import wallet_address, wallet_address_2, web3 class TestWIPDeposit: - def test_deposit(self, story_client): + def test_deposit(self, story_client: StoryClient): """Test depositing IP to WIP""" - ip_amt = Web3.to_wei(1, "ether") # or Web3.to_wei("0.01", 'ether') + ip_amt = web3.to_wei(1, "ether") # or Web3.to_wei("0.01", 'ether') # Get balances before deposit balance_before = story_client.get_wallet_balance() @@ -37,9 +36,9 @@ def test_deposit(self, story_client): class TestWIPTransfer: - def test_transfer(self, story_client): + def test_transfer(self, story_client: StoryClient): """Test transferring WIP""" - transfer_amount = Web3.to_wei("0.01", "ether") + transfer_amount = web3.to_wei("0.01", "ether") # Get balances before transfer sender_wip_before = story_client.WIP.balance_of(wallet_address) @@ -69,7 +68,7 @@ def test_transfer(self, story_client): class TestWIPWithdraw: - def test_withdraw(self, story_client): + def test_withdraw(self, story_client: StoryClient): """Test withdrawing WIP to IP""" # Get balances before withdrawal balance_before = story_client.get_wallet_balance() From cb4f09338d3f7bc57b926d993a6aa22aab87535d Mon Sep 17 00:00:00 2001 From: Bonnie Date: Mon, 4 Aug 2025 17:03:10 +0800 Subject: [PATCH 12/12] Enhance unit tests --- tests/unit/resources/test_ip_account.py | 10 +-------- tests/unit/resources/test_ip_asset.py | 10 +-------- tests/unit/resources/test_license.py | 10 +-------- tests/unit/resources/test_royalty.py | 28 ++----------------------- tests/unit/test_story_client.py | 26 +---------------------- 5 files changed, 6 insertions(+), 78 deletions(-) diff --git a/tests/unit/resources/test_ip_account.py b/tests/unit/resources/test_ip_account.py index 3548279..0c95e5b 100644 --- a/tests/unit/resources/test_ip_account.py +++ b/tests/unit/resources/test_ip_account.py @@ -1,18 +1,10 @@ -import os -import sys from unittest.mock import MagicMock, patch import pytest from eth_utils import is_address, to_checksum_address from web3 import Web3 -from src.story_protocol_python_sdk.resources.IPAccount import IPAccount - -# Ensure the src directory is in the Python path -current_dir = os.path.dirname(__file__) -src_path = os.path.abspath(os.path.join(current_dir, "..", "..", "..")) -if src_path not in sys.path: - sys.path.append(src_path) +from story_protocol_python_sdk.resources.IPAccount import IPAccount # Constants ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" diff --git a/tests/unit/resources/test_ip_asset.py b/tests/unit/resources/test_ip_asset.py index 1d3fb09..8fe3917 100644 --- a/tests/unit/resources/test_ip_asset.py +++ b/tests/unit/resources/test_ip_asset.py @@ -1,18 +1,10 @@ -import os -import sys from unittest.mock import MagicMock, patch import pytest from eth_utils import is_address, to_checksum_address from web3 import Web3 -from src.story_protocol_python_sdk.resources.IPAsset import IPAsset - -current_dir = os.path.dirname(__file__) -src_path = os.path.abspath(os.path.join(current_dir, "..", "..", "..")) -if src_path not in sys.path: - sys.path.append(src_path) - +from story_protocol_python_sdk.resources.IPAsset import IPAsset ZERO_HASH = "0x0000000000000000000000000000000000000000000000000000000000000000" ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" diff --git a/tests/unit/resources/test_license.py b/tests/unit/resources/test_license.py index 25470c9..d2fdb50 100644 --- a/tests/unit/resources/test_license.py +++ b/tests/unit/resources/test_license.py @@ -1,18 +1,10 @@ -import os -import sys from unittest.mock import MagicMock, patch import pytest from eth_utils import is_address, to_checksum_address from web3 import Web3 -from src.story_protocol_python_sdk.resources.License import License - -current_dir = os.path.dirname(__file__) -src_path = os.path.abspath(os.path.join(current_dir, "..", "..", "..")) -if src_path not in sys.path: - sys.path.append(src_path) - +from story_protocol_python_sdk.resources.License import License ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" VALID_ADDRESS = "0x1daAE3197Bc469Cb97B917aa460a12dD95c6627c" diff --git a/tests/unit/resources/test_royalty.py b/tests/unit/resources/test_royalty.py index a01b567..246db0d 100644 --- a/tests/unit/resources/test_royalty.py +++ b/tests/unit/resources/test_royalty.py @@ -1,34 +1,10 @@ -import os -import sys from unittest.mock import patch import pytest - -# Load environment variables from .env file -from dotenv import load_dotenv from web3 import Web3 -from src.story_protocol_python_sdk.resources.Royalty import Royalty - -# Ensure the src directory is in the Python path -current_dir = os.path.dirname(__file__) -src_path = os.path.abspath(os.path.join(current_dir, "..", "..", "..")) -if src_path not in sys.path: - sys.path.append(src_path) - -load_dotenv() -private_key = os.getenv("WALLET_PRIVATE_KEY") -rpc_url = os.getenv("RPC_PROVIDER_URL") - -# Initialize Web3 -web3 = Web3(Web3.HTTPProvider(rpc_url)) - -# Check if connected -if not web3.is_connected(): - raise Exception("Failed to connect to Web3 provider") - -# Set up the account with the private key -account = web3.eth.account.from_key(private_key) +from story_protocol_python_sdk.resources.Royalty import Royalty +from tests.integration.config.test_config import account, web3 @pytest.fixture diff --git a/tests/unit/test_story_client.py b/tests/unit/test_story_client.py index 455243e..f5205cd 100644 --- a/tests/unit/test_story_client.py +++ b/tests/unit/test_story_client.py @@ -1,8 +1,4 @@ -import os - import pytest -from dotenv import load_dotenv -from web3 import Web3 from story_protocol_python_sdk.resources.IPAccount import IPAccount from story_protocol_python_sdk.resources.IPAsset import IPAsset @@ -10,29 +6,9 @@ from story_protocol_python_sdk.resources.Permission import Permission from story_protocol_python_sdk.resources.Royalty import Royalty from story_protocol_python_sdk.story_client import StoryClient +from tests.integration.config.test_config import account, web3 from tests.unit.fixtures.data import CHAIN_ID -# Load environment variables from .env file -load_dotenv() -private_key = os.getenv("WALLET_PRIVATE_KEY") -rpc_url = os.getenv("RPC_PROVIDER_URL") - -# Ensure the environment variables are set -if not private_key or not rpc_url: - raise ValueError( - "Please set WALLET_PRIVATE_KEY and RPC_PROVIDER_URL in the .env file" - ) - -# Initialize Web3 -web3 = Web3(Web3.HTTPProvider(rpc_url)) - -# Check if connected -if not web3.is_connected(): - raise Exception("Failed to connect to Web3 provider") - -# Set up the account with the private key -account = web3.eth.account.from_key(private_key) - @pytest.fixture def story_client():