Skip to content
Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.
- Added Issue Reminder (no-PR) bot, .github/scripts/issue_reminder_no_pr.sh and .github/workflows/bot-issue-reminder-no-pr.yml to automatically detect assigned issues with no linked pull requests for 7+ days and post a gentle ReminderBot comment.(#951)
- Add new `.github/ISSUE_TEMPLATE/05_intermediate_issue.yml` file (1072)(https://github.com/hiero-ledger/hiero-sdk-python/issues/1072)
- Add a workflow to notify the team when issues are labeled as “good first issues” or identified as candidates for that label: `bot-gfi-notify-team.yml`(#1115)
- Added __str__ and __repr__ to AccountBalance

### Changed
- Move `account_allowance_delete_transaction_hbar.py` from `examples/` to `examples/account/` for better organization (#1003)
Expand Down
6 changes: 2 additions & 4 deletions examples/query/account_balance_query_2.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,9 @@ def get_account_balance(client: Client, account_id: AccountId):
CryptoGetAccountBalanceQuery().set_account_id(account_id).execute(client)
)
print("✅ Account balance retrieved successfully!")
# Print account balance with account_id context
print(f"💰 HBAR Balance for {account_id}: {account_balance.hbars} hbars")
# Display token balances
print("💎 Token Balances:")
for token_id, balance in account_balance.token_balances.items():
print(f" - Token ID {token_id}: {balance} units")
# Alternatively, you can use: print(account_balance)
return account_balance
except (ValueError, TypeError, RuntimeError, ConnectionError) as error:
print(f"Error retrieving account balance: {error}")
Expand Down
28 changes: 28 additions & 0 deletions src/hiero_sdk_python/account/account_balance.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,31 @@ def _from_proto(cls, proto: CryptoGetAccountBalanceResponse) -> "AccountBalance"
token_balances[token_id] = balance

return cls(hbars=hbars, token_balances=token_balances)

def __str__(self) -> str:
"""
Returns a human-friendly string representation of the account balance.

Returns:
str: A string showing HBAR balance and token balances.
"""
lines = [f"HBAR Balance: {self.hbars} hbars"]
if self.token_balances:
lines.append("Token Balances:")
for token_id, balance in self.token_balances.items():
lines.append(f" - Token ID {token_id}: {balance} units")
return "\n".join(lines)

def __repr__(self) -> str:
"""
Returns a developer-friendly string representation of the account balance.

Returns:
str: A string representation that shows the key attributes.
"""
token_balances_repr = (
f"{{{', '.join(f'{token_id!r}: {balance}' for token_id, balance in self.token_balances.items())}}}"
if self.token_balances
else "{}"
)
return f"AccountBalance(hbars={self.hbars!r}, token_balances={token_balances_repr})"
87 changes: 87 additions & 0 deletions tests/unit/test_account_balance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
"""Tests for the AccountBalance class."""

import pytest

from hiero_sdk_python.account.account_balance import AccountBalance
from hiero_sdk_python.hbar import Hbar
from hiero_sdk_python.tokens.token_id import TokenId

pytestmark = pytest.mark.unit


def test_account_balance_str_with_hbars_only():
"""Test __str__ method with only hbars."""
hbars = Hbar(10)
account_balance = AccountBalance(hbars=hbars)

result = str(account_balance)

assert "HBAR Balance:" in result
assert "10.00000000 ℏ" in result
assert "hbars" in result
# Should not include token balances section when empty
assert "Token Balances:" not in result


def test_account_balance_str_with_token_balances():
"""Test __str__ method with hbars and token balances."""
hbars = Hbar(10)
token_id_1 = TokenId(0, 0, 100)
token_id_2 = TokenId(0, 0, 200)
token_balances = {token_id_1: 1000, token_id_2: 500}
account_balance = AccountBalance(hbars=hbars, token_balances=token_balances)

result = str(account_balance)

assert "HBAR Balance:" in result
assert "10.00000000 ℏ" in result
assert " hbars" in result
assert "Token Balances:" in result
assert " - Token ID 0.0.100: 1000 units" in result
assert " - Token ID 0.0.200: 500 units" in result


def test_account_balance_str_with_empty_token_balances():
"""Test __str__ method with empty token balances dict."""
hbars = Hbar(5.5)
account_balance = AccountBalance(hbars=hbars, token_balances={})

result = str(account_balance)

assert "HBAR Balance:" in result
assert "5.50000000 ℏ" in result
assert " hbars" in result
# Should not include token balances section when empty
assert "Token Balances:" not in result


def test_account_balance_repr_with_hbars_only():
"""Test __repr__ method with only hbars."""
hbars = Hbar(10)
account_balance = AccountBalance(hbars=hbars)

result = repr(account_balance)

assert "AccountBalance" in result
assert "hbars=" in result
assert "token_balances={}" in result
assert "Hbar(" in result


def test_account_balance_repr_with_token_balances():
"""Test __repr__ method with hbars and token balances."""
hbars = Hbar(10)
token_id_1 = TokenId(0, 0, 100)
token_id_2 = TokenId(0, 0, 200)
token_balances = {token_id_1: 1000, token_id_2: 500}
account_balance = AccountBalance(hbars=hbars, token_balances=token_balances)

result = repr(account_balance)

assert "AccountBalance" in result
assert "hbars=" in result
assert "token_balances=" in result
assert "0.0.100" in result or "TokenId" in result
assert "1000" in result
assert "500" in result