From c5628ebce7fd12ad78ed7ec21edbdb1eaac0fa1f Mon Sep 17 00:00:00 2001 From: Bonnie Date: Wed, 26 Nov 2025 17:20:46 +0800 Subject: [PATCH 1/4] feat: create a extend private key use private key --- tests/integration/config/test_config.py | 13 +++++-- tests/integration/config/utils.py | 39 ++++++++++++++++++++ tests/integration/conftest.py | 49 +++++++++++++++++-------- 3 files changed, 82 insertions(+), 19 deletions(-) diff --git a/tests/integration/config/test_config.py b/tests/integration/config/test_config.py index 8b3248dd..7c55ecc3 100644 --- a/tests/integration/config/test_config.py +++ b/tests/integration/config/test_config.py @@ -3,13 +3,16 @@ from dotenv import load_dotenv from web3 import Web3 +from tests.integration.config.utils import ( + create_xprv_from_private_key, + get_private_key_from_xprv, +) + # 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") @@ -23,8 +26,12 @@ # Set up the account with the private key account = web3.eth.account.from_key(private_key) +# Create the secondary account via extended private key +xprv = create_xprv_from_private_key(private_key) +private_key_2 = get_private_key_from_xprv(xprv) account_2 = web3.eth.account.from_key(private_key_2) - +wallet_address_2 = account_2.address +print(f"Account 2: {account_2.address}") # Export all configuration __all__ = [ "web3", diff --git a/tests/integration/config/utils.py b/tests/integration/config/utils.py index 74648030..efc343e3 100644 --- a/tests/integration/config/utils.py +++ b/tests/integration/config/utils.py @@ -1,4 +1,5 @@ import hashlib +import hmac import os import base58 @@ -26,6 +27,44 @@ CORE_METADATA_MODULE = "0x6E81a25C99C6e8430aeC7353325EB138aFE5DC16" +def create_xprv_from_private_key(private_key: str) -> str: + """ + Create an extended private key (xprv) using a private key as seed. + + Args: + private_key: The private key (hex string with or without 0x prefix) + + Returns: + xprv string in base58check format + """ + seed = bytes.fromhex(private_key.removeprefix("0x")) + hmac_result = hmac.new(b"Bitcoin seed", seed, hashlib.sha512).digest() + + xprv_bytes = ( + bytes.fromhex("0488ADE4") + + bytes(9) + + hmac_result[32:] + + bytes([0]) + + hmac_result[:32] + ) + checksum = hashlib.sha256(hashlib.sha256(xprv_bytes).digest()).digest()[:4] + return base58.b58encode(xprv_bytes + checksum).decode() + + +def get_private_key_from_xprv(xprv: str) -> str: + """ + Extract the private key from an xprv. + + Args: + xprv: Extended private key in base58check format + + Returns: + Private key as hex string with 0x prefix + """ + decoded = base58.b58decode(xprv) + return "0x" + decoded[46:78].hex() + + 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/conftest.py b/tests/integration/conftest.py index 5df41ba0..363e6fe8 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -11,7 +11,7 @@ ROYALTY_POLICY_LAP_ADDRESS, ZERO_ADDRESS, ) -from tests.integration.config.test_config import account, account_2, web3 +from tests.integration.config.test_config import account, account_2, private_key, web3 from tests.integration.config.utils import MockERC20, approve, get_story_client from tests.integration.setup_for_integration import PIL_LICENSE_TEMPLATE @@ -25,22 +25,25 @@ def story_client() -> StoryClient: @pytest.fixture(scope="session") def story_client_2() -> StoryClient: """Fixture to provide the secondary story client""" - return get_story_client(web3, account_2) + if not private_key: + raise ValueError("Private key is not set") - -@pytest.fixture(scope="module") -def nft_collection(story_client: StoryClient): - """Fixture to provide the SPG NFT collection""" - tx_data = story_client.NFTClient.create_nft_collection( - name="test-collection", - symbol="TEST", - max_supply=100, - is_public_minting=True, - mint_open=True, - contract_uri="test-uri", - mint_fee_recipient=account.address, - ) - return tx_data["nft_contract"] + story_client_2 = get_story_client(web3, account_2) + balance = story_client_2.get_wallet_balance() + if balance < web3.to_wei(5, "ether"): + tx = { + "from": account.address, + "to": account_2.address, + "value": web3.to_wei(5, "ether"), + "nonce": web3.eth.get_transaction_count(account.address), + "gas": 21000, + "gasPrice": web3.eth.gas_price, + "chainId": web3.eth.chain_id, + } + signed_tx = account.sign_transaction(tx) + tx_hash = web3.eth.send_raw_transaction(signed_tx.raw_transaction) + web3.eth.wait_for_transaction_receipt(tx_hash) + return story_client_2 @pytest.fixture(scope="module") @@ -124,3 +127,17 @@ def mint_and_approve_license_token( ) return license_token_ids + + +@pytest.fixture(scope="module") +def nft_collection(story_client: StoryClient): + tx_data = story_client.NFTClient.create_nft_collection( + name="test-collection", + symbol="TEST", + max_supply=100, + is_public_minting=True, + mint_open=True, + contract_uri="test-uri", + mint_fee_recipient=account.address, + ) + return tx_data["nft_contract"] From 709d1a80ff3fb24f02c1951a65e95b90fecf77c1 Mon Sep 17 00:00:00 2001 From: Bonnie Date: Thu, 27 Nov 2025 13:59:57 +0800 Subject: [PATCH 2/4] Fix: the fail test --- tests/integration/config/test_config.py | 1 - tests/integration/test_integration_transaction_utils.py | 2 ++ tests/unit/resources/test_ip_asset.py | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/integration/config/test_config.py b/tests/integration/config/test_config.py index 7c55ecc3..863ecf5d 100644 --- a/tests/integration/config/test_config.py +++ b/tests/integration/config/test_config.py @@ -31,7 +31,6 @@ private_key_2 = get_private_key_from_xprv(xprv) account_2 = web3.eth.account.from_key(private_key_2) wallet_address_2 = account_2.address -print(f"Account 2: {account_2.address}") # Export all configuration __all__ = [ "web3", diff --git a/tests/integration/test_integration_transaction_utils.py b/tests/integration/test_integration_transaction_utils.py index fd14c5d7..713e6455 100644 --- a/tests/integration/test_integration_transaction_utils.py +++ b/tests/integration/test_integration_transaction_utils.py @@ -301,3 +301,5 @@ def build_tx(tx_options): build_tx, tx_options={"wait_for_receipt": True, "timeout": 0.001}, ) + + time.sleep(1) # Wait for the transaction to be mined diff --git a/tests/unit/resources/test_ip_asset.py b/tests/unit/resources/test_ip_asset.py index a09e87df..d4278258 100644 --- a/tests/unit/resources/test_ip_asset.py +++ b/tests/unit/resources/test_ip_asset.py @@ -2061,7 +2061,6 @@ def test_batch_mint_transaction_success( ) as mock_build_multicall_transaction: result = ip_asset.batch_mint_and_register_ip(requests=requests) - print(mock_build_multicall_transaction.call_args[0][0]) assert mock_build_multicall_transaction.call_args[0][0] == [ b"encoded_data", b"encoded_data", From dc072bff43245d0085727a1e5680181e54ca4f52 Mon Sep 17 00:00:00 2001 From: Bonnie Date: Thu, 27 Nov 2025 14:04:33 +0800 Subject: [PATCH 3/4] feat: add WALLET_ADDRESS to .env-example for configuration clarity --- .env-example | 1 + 1 file changed, 1 insertion(+) diff --git a/.env-example b/.env-example index 360b8bbc..15460631 100644 --- a/.env-example +++ b/.env-example @@ -1,3 +1,4 @@ WALLET_PRIVATE_KEY=YOUR-PRIVATE-WALLET-KEY +WALLET_ADDRESS=YOUR-WALLET-ADDRESS RPC_PROVIDER_URL=YOUR_RPC_URL ETHERSCAN_API_KEY=YOUR-ETHERSCAN-API-KEY-HERE From 8f1a2cf982896b5e1a4b7050e517c2f54743deb4 Mon Sep 17 00:00:00 2001 From: Bonnie Date: Thu, 27 Nov 2025 14:57:12 +0800 Subject: [PATCH 4/4] fix: increase sleep duration in transaction mining test to ensure reliability --- tests/integration/test_integration_transaction_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/test_integration_transaction_utils.py b/tests/integration/test_integration_transaction_utils.py index 713e6455..6565c50e 100644 --- a/tests/integration/test_integration_transaction_utils.py +++ b/tests/integration/test_integration_transaction_utils.py @@ -302,4 +302,4 @@ def build_tx(tx_options): tx_options={"wait_for_receipt": True, "timeout": 0.001}, ) - time.sleep(1) # Wait for the transaction to be mined + time.sleep(5) # Wait for the transaction to be mined