Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions python/kaspa/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,13 @@ class AccountKind:
Returns:
str: The account kind as a string.
"""
def __repr__(self) -> builtins.str:
r"""
The detailed string representation.

Returns:
str: The account kind as a repr string.
"""
def to_string(self) -> builtins.str:
r"""
Get the string representation.
Expand Down
8 changes: 8 additions & 0 deletions src/wallet/core/account/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ impl PyAccountKind {
self.py_to_string()
}

/// The detailed string representation.
///
/// Returns:
/// str: The account kind as a repr string.
pub fn __repr__(&self) -> String {
format!("AccountKind('{}')", self.0.as_str())
}

/// Get the string representation.
///
/// Returns:
Expand Down
125 changes: 125 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
Shared fixtures for Kaspa Python SDK tests.
"""

import os
import shutil
import uuid

import pytest
import pytest_asyncio

Expand All @@ -14,6 +18,7 @@
Address,
RpcClient,
Resolver,
Wallet,
)


Expand Down Expand Up @@ -146,3 +151,123 @@ def test_address(network_id):
if network_id.startswith("testnet"):
return "kaspatest:qr0lr4ml9fn3chekrqmjdkergxl93l4wrk3dankcgvjq776s9wn9jhtkdksae"
return TEST_MAINNET_ADDRESS


# =============================================================================
# Wallet Fixtures (Unit-test scope — no network required)
# =============================================================================

# Default passwords used across wallet unit tests.
TEST_WALLET_SECRET = "test-wallet-secret"
TEST_NEW_WALLET_SECRET = "test-wallet-secret-new"

# Directory where the local wallet store persists wallet files.
_KASPA_LOCAL_STORE_DIR = os.path.expanduser("~/.kaspa")


def cleanup_wallet_files(filename: str) -> None:
"""Remove any wallet/transaction artifacts left by a test run.

Sweeps both `~/.kaspa/` (default LocalStore folder) and the current
working directory. The CWD sweep covers `wallet_rename` with a bare
filename — upstream `Storage::rename_sync` treats the argument as a
plain `PathBuf`, so the renamed file lands in the pytest CWD, not
`~/.kaspa/`.
"""
root = os.path.join(_KASPA_LOCAL_STORE_DIR, filename)
cwd_root = os.path.join(os.getcwd(), filename)
candidates = (
f"{root}.wallet",
f"{root}.transactions",
root,
cwd_root,
f"{cwd_root}.wallet",
f"{cwd_root}.transactions",
)
for candidate in candidates:
if os.path.isdir(candidate):
shutil.rmtree(candidate, ignore_errors=True)
else:
try:
os.remove(candidate)
except (FileNotFoundError, IsADirectoryError, PermissionError):
pass


@pytest.fixture
def unique_wallet_filename() -> str:
"""Return a unique wallet filename (without extension) for isolated tests."""
return f"unit-test-{uuid.uuid4().hex[:12]}"


@pytest_asyncio.fixture
async def started_wallet():
"""A started Wallet (testnet-10) with no wallet file opened.

Yields the Wallet; `stop()` is awaited on teardown.
"""
wallet = Wallet(network_id="testnet-10", resolver=Resolver())
await wallet.start()
try:
yield wallet
finally:
if wallet.is_open:
await wallet.wallet_close()
await wallet.stop()


@pytest_asyncio.fixture
async def open_wallet(unique_wallet_filename):
"""A started Wallet with a freshly created wallet file opened.

Yields (wallet, filename). Cleans up the wallet file on teardown.
"""
wallet = Wallet(network_id="testnet-10", resolver=Resolver())
await wallet.start()
# The wallet title is also used as the filename when the wallet is
# re-imported from an exported payload; keep it unique per-test so
# export/import flows don't collide with other tests on disk.
title = unique_wallet_filename
try:
await wallet.wallet_create(
wallet_secret=TEST_WALLET_SECRET,
filename=unique_wallet_filename,
overwrite_wallet_storage=True,
title=title,
)
yield wallet, unique_wallet_filename
finally:
if wallet.is_open:
await wallet.wallet_close()
await wallet.stop()
cleanup_wallet_files(unique_wallet_filename)
cleanup_wallet_files(title)


@pytest_asyncio.fixture
async def connected_wallet(unique_wallet_filename, network_id, rpc_url):
"""A started Wallet with a fresh wallet file opened and RPC connected.

Yields (wallet, filename). Disconnects + closes + cleans up on teardown.
Requires `--rpc-url` to be passed (integration tier).
"""
wallet = Wallet(network_id=network_id, url=rpc_url)
await wallet.start()
title = unique_wallet_filename
try:
await wallet.wallet_create(
wallet_secret=TEST_WALLET_SECRET,
filename=unique_wallet_filename,
overwrite_wallet_storage=True,
title=title,
)
await wallet.connect(block_async_connect=True)
yield wallet, unique_wallet_filename
finally:
if wallet.rpc.is_connected:
await wallet.disconnect()
if wallet.is_open:
await wallet.wallet_close()
await wallet.stop()
cleanup_wallet_files(unique_wallet_filename)
cleanup_wallet_files(title)
Loading
Loading