Skip to content

Commit 3ebc50a

Browse files
chore: bump version to 0.3.18
1 parent 5ea0515 commit 3ebc50a

File tree

10 files changed

+91
-75
lines changed

10 files changed

+91
-75
lines changed

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
setup(
77
name="story_protocol_python_sdk",
8-
version="0.3.17",
8+
version="0.3.18",
99
packages=find_packages(where="src", exclude=["tests"]),
1010
package_dir={"": "src"},
1111
install_requires=["web3>=7.0.0", "pytest", "python-dotenv", "base58"],

src/story_protocol_python_sdk/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__ = "0.3.17"
1+
__version__ = "0.3.18"
22

33
from .resources.Dispute import Dispute
44
from .resources.IPAccount import IPAccount

src/story_protocol_python_sdk/abi/GroupingModule/GroupingModule_client.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ def removeIp(self, groupIpId, ipIds):
4747
return self.contract.functions.removeIp(groupIpId, ipIds).transact()
4848

4949
def build_removeIp_transaction(self, groupIpId, ipIds, tx_params):
50-
return self.contract.functions.removeIp(
51-
groupIpId, ipIds
52-
).build_transaction(tx_params)
50+
return self.contract.functions.removeIp(groupIpId, ipIds).build_transaction(
51+
tx_params
52+
)
5353

5454
def claimReward(self, groupId, token, ipIds):
5555
return self.contract.functions.claimReward(groupId, token, ipIds).transact()

src/story_protocol_python_sdk/abi/LicenseToken/LicenseToken_client.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,7 @@ def __init__(self, web3: Web3):
3232
self.contract = self.web3.eth.contract(address=contract_address, abi=abi)
3333

3434
def getTotalTokensByLicensor(self, licensorIpId):
35-
return self.contract.functions.getTotalTokensByLicensor(
36-
licensorIpId
37-
).call()
35+
return self.contract.functions.getTotalTokensByLicensor(licensorIpId).call()
3836

3937
def ownerOf(self, tokenId):
4038
return self.contract.functions.ownerOf(tokenId).call()

src/story_protocol_python_sdk/resources/IPAsset.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2417,7 +2417,7 @@ def is_registered(self, ip_id: str) -> bool:
24172417
"""
24182418
if not ip_id:
24192419
raise ValueError("is_registered: ip_id is required")
2420-
2420+
24212421
if not self.web3.is_address(ip_id):
24222422
raise ValueError(f"is_registered: invalid IP ID address format: {ip_id}")
24232423

@@ -2443,7 +2443,9 @@ def _parse_tx_ip_registered_event(self, tx_receipt: dict) -> list[RegisteredIP]:
24432443
)
24442444
registered_ips.append(
24452445
RegisteredIP(
2446-
ip_id=self.web3.to_checksum_address(event_result["args"]["ipId"]),
2446+
ip_id=self.web3.to_checksum_address(
2447+
event_result["args"]["ipId"]
2448+
),
24472449
token_id=event_result["args"]["tokenId"],
24482450
)
24492451
)

src/story_protocol_python_sdk/resources/Royalty.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,9 @@ def batch_claim_all_revenue(
260260
receipts = []
261261
claimed_tokens = []
262262

263-
use_multicall = options.get("use_multicall_when_possible", True) if options else True
263+
use_multicall = (
264+
options.get("use_multicall_when_possible", True) if options else True
265+
)
264266

265267
# If only 1 ancestor IP or multicall is disabled, call claim_all_revenue for each
266268
if len(ancestor_ips) == 1 or not use_multicall:
@@ -338,14 +340,18 @@ def batch_claim_all_revenue(
338340
wip_claimable_amounts = 0
339341

340342
for claimer in claimers:
341-
owns_claimer, is_claimer_ip, ip_account = self._get_claimer_info(claimer)
343+
owns_claimer, is_claimer_ip, ip_account = self._get_claimer_info(
344+
claimer
345+
)
342346

343347
# If ownsClaimer is false, skip
344348
if not owns_claimer:
345349
continue
346350

347351
filter_claimed_tokens = [
348-
token for token in aggregated_claimed_tokens if token["claimer"] == claimer
352+
token
353+
for token in aggregated_claimed_tokens
354+
if token["claimer"] == claimer
349355
]
350356

351357
# Transfer claimed tokens from IP to wallet if wallet owns IP

src/story_protocol_python_sdk/utils/transaction_utils.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,7 @@ def _get_transaction_options(
4444
# Gas: bump for replacement, or use tx_options
4545
if bump_gas:
4646
try:
47-
opts["gasPrice"] = int(
48-
web3.eth.gas_price * REPLACEMENT_GAS_BUMP_RATIO
49-
)
47+
opts["gasPrice"] = int(web3.eth.gas_price * REPLACEMENT_GAS_BUMP_RATIO)
5048
except Exception:
5149
opts["gasPrice"] = web3.to_wei(2, "gwei")
5250
else:
@@ -65,10 +63,7 @@ def _get_transaction_options(
6563
def _is_retryable_send_error(exc: Exception) -> bool:
6664
"""True if we should retry send (same nonce, higher gas)."""
6765
msg = str(exc).lower()
68-
return (
69-
"replacement transaction underpriced" in msg
70-
or "nonce too low" in msg
71-
)
66+
return "replacement transaction underpriced" in msg or "nonce too low" in msg
7267

7368

7469
def _send_one(

tests/integration/test_integration_group.py

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -376,9 +376,7 @@ def _normalize_address(web3, addr: str) -> str:
376376
class TestAddIpsToGroupAndRemoveIpsFromGroup:
377377
"""Integration tests for add_ips_to_group and remove_ips_from_group with strict on-chain verification."""
378378

379-
def test_add_ips_to_group(
380-
self, story_client: StoryClient, nft_collection: Address
381-
):
379+
def test_add_ips_to_group(self, story_client: StoryClient, nft_collection: Address):
382380
"""Test adding IPs to an existing group; verify chain state via AddedIpToGroup event and get_claimable_reward."""
383381
result1 = GroupTestHelper.mint_and_register_ip_asset_with_pil_terms(
384382
story_client, nft_collection
@@ -403,17 +401,19 @@ def test_add_ips_to_group(
403401
assert isinstance(result["tx_hash"], str)
404402
assert len(result["tx_hash"]) > 0
405403
# Strict: verify on-chain AddedIpToGroup event
406-
assert "tx_receipt" in result, "add_ips_to_group must return tx_receipt for verification"
404+
assert (
405+
"tx_receipt" in result
406+
), "add_ips_to_group must return tx_receipt for verification"
407407
added_events = story_client.Group.get_added_ip_to_group_events(
408408
result["tx_receipt"]
409409
)
410410
assert len(added_events) == 1
411-
assert _normalize_address(story_client.web3, added_events[0]["groupId"]) == _normalize_address(
412-
story_client.web3, group_ip_id
413-
)
414-
assert set(_normalize_address(story_client.web3, a) for a in added_events[0]["ipIds"]) == {
415-
_normalize_address(story_client.web3, ip_id2)
416-
}
411+
assert _normalize_address(
412+
story_client.web3, added_events[0]["groupId"]
413+
) == _normalize_address(story_client.web3, group_ip_id)
414+
assert set(
415+
_normalize_address(story_client.web3, a) for a in added_events[0]["ipIds"]
416+
) == {_normalize_address(story_client.web3, ip_id2)}
417417
# Verify new member is in group: get_claimable_reward for [ip_id1, ip_id2] should succeed
418418
claimable = story_client.Group.get_claimable_reward(
419419
group_ip_id=group_ip_id,
@@ -454,12 +454,12 @@ def test_add_ips_to_group_with_max_reward_share(
454454
result["tx_receipt"]
455455
)
456456
assert len(added_events) == 1
457-
assert _normalize_address(story_client.web3, added_events[0]["groupId"]) == _normalize_address(
458-
story_client.web3, group_ip_id
459-
)
460-
assert set(_normalize_address(story_client.web3, a) for a in added_events[0]["ipIds"]) == {
461-
_normalize_address(story_client.web3, ip_id2)
462-
}
457+
assert _normalize_address(
458+
story_client.web3, added_events[0]["groupId"]
459+
) == _normalize_address(story_client.web3, group_ip_id)
460+
assert set(
461+
_normalize_address(story_client.web3, a) for a in added_events[0]["ipIds"]
462+
) == {_normalize_address(story_client.web3, ip_id2)}
463463

464464
def test_remove_ips_from_group(
465465
self, story_client: StoryClient, nft_collection: Address
@@ -492,12 +492,12 @@ def test_remove_ips_from_group(
492492
result["tx_receipt"]
493493
)
494494
assert len(removed_events) == 1
495-
assert _normalize_address(story_client.web3, removed_events[0]["groupId"]) == _normalize_address(
496-
story_client.web3, group_ip_id
497-
)
498-
assert set(_normalize_address(story_client.web3, a) for a in removed_events[0]["ipIds"]) == {
499-
_normalize_address(story_client.web3, ip_id2)
500-
}
495+
assert _normalize_address(
496+
story_client.web3, removed_events[0]["groupId"]
497+
) == _normalize_address(story_client.web3, group_ip_id)
498+
assert set(
499+
_normalize_address(story_client.web3, a) for a in removed_events[0]["ipIds"]
500+
) == {_normalize_address(story_client.web3, ip_id2)}
501501
# After remove, only ip_id1 remains; get_claimable_reward for [ip_id1] must succeed
502502
claimable = story_client.Group.get_claimable_reward(
503503
group_ip_id=group_ip_id,
@@ -540,7 +540,9 @@ def test_add_then_remove_ips_from_group(
540540
add_result["tx_receipt"]
541541
)
542542
assert len(added_events) == 1
543-
assert set(_normalize_address(story_client.web3, a) for a in added_events[0]["ipIds"]) == {
543+
assert set(
544+
_normalize_address(story_client.web3, a) for a in added_events[0]["ipIds"]
545+
) == {
544546
_normalize_address(story_client.web3, ip_id2),
545547
_normalize_address(story_client.web3, ip_id3),
546548
}
@@ -556,9 +558,9 @@ def test_add_then_remove_ips_from_group(
556558
remove_result["tx_receipt"]
557559
)
558560
assert len(removed_events) == 1
559-
assert set(_normalize_address(story_client.web3, a) for a in removed_events[0]["ipIds"]) == {
560-
_normalize_address(story_client.web3, ip_id2)
561-
}
561+
assert set(
562+
_normalize_address(story_client.web3, a) for a in removed_events[0]["ipIds"]
563+
) == {_normalize_address(story_client.web3, ip_id2)}
562564

563565
# Final state: only ip_id1 and ip_id3 are members
564566
claimable = story_client.Group.get_claimable_reward(

tests/integration/test_integration_royalty.py

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ def test_pay_royalty_invalid_amount(
153153

154154
def test_batch_claim_all_revenue_single_ancestor(self, story_client: StoryClient):
155155
"""Test batch claiming revenue using the same pattern as test_claim_all_revenue
156-
156+
157157
This test verifies that batch_claim_all_revenue works correctly by:
158158
1. Creating a derivative chain A->B->C
159159
2. Using batch_claim_all_revenue to claim revenue for A
@@ -242,8 +242,12 @@ def wrapper_derivative_with_wip(parent_ip_id, license_terms_id):
242242

243243
# Build derivative chain: A -> B -> C -> D (same as test_claim_all_revenue)
244244
ip_b = wrapper_derivative_with_wip(ip_a, license_terms_id) # B pays 100 WIP
245-
ip_c = wrapper_derivative_with_wip(ip_b, license_terms_id) # C pays 100 WIP (10 to A, 90 to B)
246-
wrapper_derivative_with_wip(ip_c, license_terms_id) # D pays 100 WIP (10 to A, 10 to B, 80 to C)
245+
ip_c = wrapper_derivative_with_wip(
246+
ip_b, license_terms_id
247+
) # C pays 100 WIP (10 to A, 90 to B)
248+
wrapper_derivative_with_wip(
249+
ip_c, license_terms_id
250+
) # D pays 100 WIP (10 to A, 10 to B, 80 to C)
247251

248252
# Batch claim revenue for IP A (should get 120 WIP: 100 from B + 10 from C + 10 from D)
249253
# Note: Only pass [ip_b, ip_c] as child_ip_ids, not ip_d, matching test_claim_all_revenue
@@ -271,13 +275,15 @@ def wrapper_derivative_with_wip(parent_ip_id, license_terms_id):
271275
assert len(response["receipts"]) >= 1
272276
assert "claimed_tokens" in response
273277
assert len(response["claimed_tokens"]) >= 1
274-
278+
275279
# Verify IP A received 120 WIP tokens (100 from B + 10 from C + 10 from D)
276280
assert response["claimed_tokens"][0]["amount"] == 120
277281

278-
def test_batch_claim_all_revenue_multiple_ancestors(self, story_client: StoryClient):
282+
def test_batch_claim_all_revenue_multiple_ancestors(
283+
self, story_client: StoryClient
284+
):
279285
"""Test batch claiming revenue from multiple ancestor IPs
280-
286+
281287
This test creates two independent derivative chains and claims revenue for both ancestors:
282288
- Chain 1: A1 -> B1 -> C1 -> D1 (A1 gets 120 WIP)
283289
- Chain 2: A2 -> B2 -> C2 (A2 gets 110 WIP)
@@ -373,7 +379,7 @@ def wrapper_derivative_with_wip(parent_ip_id, license_terms_id):
373379
spg_nft_contract=spg_nft_contract,
374380
)
375381
ip_a2 = ip_a2_response["ip_id"]
376-
382+
377383
# Attach the same license terms to IP A2
378384
story_client.License.attach_license_terms(
379385
ip_id=ip_a2,
@@ -383,7 +389,7 @@ def wrapper_derivative_with_wip(parent_ip_id, license_terms_id):
383389

384390
# Build derivative chain 2: A2 -> B2 -> C2
385391
ip_b2 = wrapper_derivative_with_wip(ip_a2, license_terms_id)
386-
ip_c2 = wrapper_derivative_with_wip(ip_b2, license_terms_id)
392+
wrapper_derivative_with_wip(ip_b2, license_terms_id)
387393

388394
# Batch claim revenue for both ancestors (disable multicall to avoid potential issues)
389395
response = story_client.Royalty.batch_claim_all_revenue(
@@ -420,11 +426,13 @@ def wrapper_derivative_with_wip(parent_ip_id, license_terms_id):
420426
assert len(response["receipts"]) >= 2
421427
assert "claimed_tokens" in response
422428
assert len(response["claimed_tokens"]) == 2 # Two ancestors claimed
423-
429+
424430
# Verify both ancestors received their expected amounts
425431
# A1 should get 120 WIP (100 from B1 + 10 from C1 + 10 from D1)
426432
# A2 should get 110 WIP (100 from B2 + 10 from C2)
427-
claimed_amounts = {token["claimer"]: token["amount"] for token in response["claimed_tokens"]}
433+
claimed_amounts = {
434+
token["claimer"]: token["amount"] for token in response["claimed_tokens"]
435+
}
428436
assert claimed_amounts[ip_a1] == 120
429437
assert claimed_amounts[ip_a2] == 110
430438

tests/unit/resources/test_batch_claim_all_revenue.py

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -78,30 +78,35 @@ def test_batch_claim_all_revenue_multiple_ancestors_with_multicall(
7878
],
7979
):
8080
with patch.object(
81-
royalty_client, "_get_claimer_info", return_value=(False, False, None)
81+
royalty_client,
82+
"_get_claimer_info",
83+
return_value=(False, False, None),
8284
):
8385
with patch(
8486
"story_protocol_python_sdk.resources.Royalty.build_and_send_transaction",
85-
return_value={"tx_hash": TX_HASH.hex(), "tx_receipt": {"logs": []}},
87+
return_value={
88+
"tx_hash": TX_HASH.hex(),
89+
"tx_receipt": {"logs": []},
90+
},
8691
):
8792
result = royalty_client.batch_claim_all_revenue(
88-
ancestor_ips=[
89-
{
90-
"ip_id": ADDRESS,
91-
"claimer": ADDRESS,
92-
"child_ip_ids": [],
93-
"royalty_policies": [],
94-
"currency_tokens": [WIP_TOKEN_ADDRESS],
95-
},
96-
{
97-
"ip_id": ACCOUNT_ADDRESS,
98-
"claimer": ACCOUNT_ADDRESS,
99-
"child_ip_ids": [],
100-
"royalty_policies": [],
101-
"currency_tokens": [WIP_TOKEN_ADDRESS],
102-
},
103-
],
104-
)
93+
ancestor_ips=[
94+
{
95+
"ip_id": ADDRESS,
96+
"claimer": ADDRESS,
97+
"child_ip_ids": [],
98+
"royalty_policies": [],
99+
"currency_tokens": [WIP_TOKEN_ADDRESS],
100+
},
101+
{
102+
"ip_id": ACCOUNT_ADDRESS,
103+
"claimer": ACCOUNT_ADDRESS,
104+
"child_ip_ids": [],
105+
"royalty_policies": [],
106+
"currency_tokens": [WIP_TOKEN_ADDRESS],
107+
},
108+
],
109+
)
105110
assert len(result["tx_hashes"]) == 1
106111
assert len(result["receipts"]) == 1
107112
assert len(result["claimed_tokens"]) == 2

0 commit comments

Comments
 (0)